From 483a8c27761c6e74a64e902d44bd48aa7e92a238 Mon Sep 17 00:00:00 2001 From: samisalehsaeed Date: Mon, 17 Jun 2024 16:45:17 +0100 Subject: [PATCH 1/3] Sami Saeed --- package-lock.json | 99 +++++++++----- package.json | 13 +- src/server.js | 55 ++++++-- test/api/standard/contacts.spec.js | 208 ++++++++++++++--------------- 4 files changed, 225 insertions(+), 150 deletions(-) diff --git a/package-lock.json b/package-lock.json index 3fb12fd..dee22db 100644 --- a/package-lock.json +++ b/package-lock.json @@ -10,12 +10,12 @@ "license": "ISC", "dependencies": { "cors": "^2.8.5", - "express": "^4.18.2", - "morgan": "^1.10.0", - "nodemon": "^3.0.1" + "express": "^4.19.2", + "morgan": "^1.10.0" }, "devDependencies": { "jest": "^29.7.0", + "nodemon": "^3.1.3", "supertest": "^6.2.3" } }, @@ -1182,7 +1182,8 @@ "node_modules/abbrev": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/abbrev/-/abbrev-1.1.1.tgz", - "integrity": "sha512-nne9/IiQ/hzIhY6pdDnbBtz7DjPTKrY00P/zvPSm5pOFkl6xuGrGnXn/VtTNNfNtAfZ9/1RtehkszU9qcTii0Q==" + "integrity": "sha512-nne9/IiQ/hzIhY6pdDnbBtz7DjPTKrY00P/zvPSm5pOFkl6xuGrGnXn/VtTNNfNtAfZ9/1RtehkszU9qcTii0Q==", + "dev": true }, "node_modules/accepts": { "version": "1.3.8", @@ -1239,6 +1240,7 @@ "version": "3.1.3", "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.3.tgz", "integrity": "sha512-KMReFUr0B4t+D+OBkjR3KYqvocp2XaSzO55UcB6mgQMd3KbcE+mWTyvVV7D/zsdEbNnV6acZUutkiHQXvTr1Rw==", + "dev": true, "dependencies": { "normalize-path": "^3.0.0", "picomatch": "^2.0.4" @@ -1383,7 +1385,8 @@ "node_modules/balanced-match": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", - "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==" + "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==", + "dev": true }, "node_modules/basic-auth": { "version": "2.0.1", @@ -1405,17 +1408,18 @@ "version": "2.2.0", "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.2.0.tgz", "integrity": "sha512-jDctJ/IVQbZoJykoeHbhXpOlNBqGNcwXJKJog42E5HDPUwQTSdjCHdihjj0DlnheQ7blbT6dHOafNAiS8ooQKA==", + "dev": true, "engines": { "node": ">=8" } }, "node_modules/body-parser": { - "version": "1.20.1", - "resolved": "https://registry.npmjs.org/body-parser/-/body-parser-1.20.1.tgz", - "integrity": "sha512-jWi7abTbYwajOytWCQc37VulmWiRae5RyTpaCyDcS5/lMdtwSz5lOpDE67srw/HYe35f1z3fDQw+3txg7gNtWw==", + "version": "1.20.2", + "resolved": "https://registry.npmjs.org/body-parser/-/body-parser-1.20.2.tgz", + "integrity": "sha512-ml9pReCu3M61kGlqoTm2umSXTlRTuGTx0bfYj+uIUKKYycG5NtSbeetV3faSU6R7ajOPw0g/J1PvK4qNy7s5bA==", "dependencies": { "bytes": "3.1.2", - "content-type": "~1.0.4", + "content-type": "~1.0.5", "debug": "2.6.9", "depd": "2.0.0", "destroy": "1.2.0", @@ -1423,7 +1427,7 @@ "iconv-lite": "0.4.24", "on-finished": "2.4.1", "qs": "6.11.0", - "raw-body": "2.5.1", + "raw-body": "2.5.2", "type-is": "~1.6.18", "unpipe": "1.0.0" }, @@ -1436,6 +1440,7 @@ "version": "1.1.11", "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", + "dev": true, "dependencies": { "balanced-match": "^1.0.0", "concat-map": "0.0.1" @@ -1445,6 +1450,7 @@ "version": "3.0.2", "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.2.tgz", "integrity": "sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==", + "dev": true, "dependencies": { "fill-range": "^7.0.1" }, @@ -1587,6 +1593,7 @@ "version": "3.5.3", "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.5.3.tgz", "integrity": "sha512-Dr3sfKRP6oTcjf2JmUmFJfeVMvXBdegxB0iVQ5eb2V10uFJUCAS8OByZdVAyVb8xXNz3GjjTgj9kLWsZTqE6kw==", + "dev": true, "funding": [ { "type": "individual", @@ -1702,7 +1709,8 @@ "node_modules/concat-map": { "version": "0.0.1", "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", - "integrity": "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==" + "integrity": "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==", + "dev": true }, "node_modules/content-disposition": { "version": "0.5.4", @@ -1730,9 +1738,9 @@ "dev": true }, "node_modules/cookie": { - "version": "0.5.0", - "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.5.0.tgz", - "integrity": "sha512-YZ3GUyn/o8gfKJlnlX7g7xq4gyO6OSuhGPKaaGssGB2qgDUS0gPgtTvoyZLTt9Ab6dC4hfc9dV5arkvc/OCmrw==", + "version": "0.6.0", + "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.6.0.tgz", + "integrity": "sha512-U71cyTamuh1CRNCfpGY6to28lxvNwPG4Guz/EVjgf3Jmzv0vlDp1atT9eS5dDjMYHucpHbWns6Lwf3BKz6svdw==", "engines": { "node": ">= 0.6" } @@ -2032,16 +2040,16 @@ } }, "node_modules/express": { - "version": "4.18.2", - "resolved": "https://registry.npmjs.org/express/-/express-4.18.2.tgz", - "integrity": "sha512-5/PsL6iGPdfQ/lKM1UuielYgv3BUoJfz1aUwU9vHZ+J7gyvwdQXFEBIEIaxeGf0GIcreATNyBExtalisDbuMqQ==", + "version": "4.19.2", + "resolved": "https://registry.npmjs.org/express/-/express-4.19.2.tgz", + "integrity": "sha512-5T6nhjsT+EOMzuck8JjBHARTHfMht0POzlA60WV2pMD3gyXw2LZnZ+ueGdNxG+0calOJcWKbpFcuzLZ91YWq9Q==", "dependencies": { "accepts": "~1.3.8", "array-flatten": "1.1.1", - "body-parser": "1.20.1", + "body-parser": "1.20.2", "content-disposition": "0.5.4", "content-type": "~1.0.4", - "cookie": "0.5.0", + "cookie": "0.6.0", "cookie-signature": "1.0.6", "debug": "2.6.9", "depd": "2.0.0", @@ -2097,6 +2105,7 @@ "version": "7.0.1", "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz", "integrity": "sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==", + "dev": true, "dependencies": { "to-regex-range": "^5.0.1" }, @@ -2189,6 +2198,7 @@ "version": "2.3.3", "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.3.tgz", "integrity": "sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==", + "dev": true, "hasInstallScript": true, "optional": true, "os": [ @@ -2283,6 +2293,7 @@ "version": "5.1.2", "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz", "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==", + "dev": true, "dependencies": { "is-glob": "^4.0.1" }, @@ -2422,7 +2433,8 @@ "node_modules/ignore-by-default": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/ignore-by-default/-/ignore-by-default-1.0.1.tgz", - "integrity": "sha512-Ius2VYcGNk7T90CppJqcIkS5ooHUZyIQK+ClZfMfMNFEF9VSE73Fq+906u/CWu92x4gzZMWOwfFYckPObzdEbA==" + "integrity": "sha512-Ius2VYcGNk7T90CppJqcIkS5ooHUZyIQK+ClZfMfMNFEF9VSE73Fq+906u/CWu92x4gzZMWOwfFYckPObzdEbA==", + "dev": true }, "node_modules/import-local": { "version": "3.1.0", @@ -2485,6 +2497,7 @@ "version": "2.1.0", "resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-2.1.0.tgz", "integrity": "sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==", + "dev": true, "dependencies": { "binary-extensions": "^2.0.0" }, @@ -2508,6 +2521,7 @@ "version": "2.1.1", "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", "integrity": "sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==", + "dev": true, "engines": { "node": ">=0.10.0" } @@ -2534,6 +2548,7 @@ "version": "4.0.3", "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz", "integrity": "sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==", + "dev": true, "dependencies": { "is-extglob": "^2.1.1" }, @@ -2545,6 +2560,7 @@ "version": "7.0.0", "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz", "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==", + "dev": true, "engines": { "node": ">=0.12.0" } @@ -3511,6 +3527,7 @@ "version": "3.1.2", "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", + "dev": true, "dependencies": { "brace-expansion": "^1.1.7" }, @@ -3576,9 +3593,10 @@ "dev": true }, "node_modules/nodemon": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/nodemon/-/nodemon-3.0.2.tgz", - "integrity": "sha512-9qIN2LNTrEzpOPBaWHTm4Asy1LxXLSickZStAQ4IZe7zsoIpD/A7LWxhZV3t4Zu352uBcqVnRsDXSMR2Sc3lTA==", + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/nodemon/-/nodemon-3.1.3.tgz", + "integrity": "sha512-m4Vqs+APdKzDFpuaL9F9EVOF85+h070FnkHVEoU4+rmT6Vw0bmNl7s61VEkY/cJkL7RCv1p4urnUDUMrS5rk2w==", + "dev": true, "dependencies": { "chokidar": "^3.5.2", "debug": "^4", @@ -3606,6 +3624,7 @@ "version": "4.3.4", "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz", "integrity": "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==", + "dev": true, "dependencies": { "ms": "2.1.2" }, @@ -3622,6 +3641,7 @@ "version": "3.0.0", "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", "integrity": "sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==", + "dev": true, "engines": { "node": ">=4" } @@ -3630,6 +3650,7 @@ "version": "6.0.0", "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz", "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==", + "dev": true, "dependencies": { "yallist": "^4.0.0" }, @@ -3640,12 +3661,14 @@ "node_modules/nodemon/node_modules/ms": { "version": "2.1.2", "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", - "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==" + "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", + "dev": true }, "node_modules/nodemon/node_modules/semver": { "version": "7.5.4", "resolved": "https://registry.npmjs.org/semver/-/semver-7.5.4.tgz", "integrity": "sha512-1bCSESV6Pv+i21Hvpxp3Dx+pSD8lIPt8uVjRrxAUt/nbswYc+tK6Y2btiULjd4+fnq15PX+nqQDC7Oft7WkwcA==", + "dev": true, "dependencies": { "lru-cache": "^6.0.0" }, @@ -3660,6 +3683,7 @@ "version": "5.5.0", "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", + "dev": true, "dependencies": { "has-flag": "^3.0.0" }, @@ -3670,12 +3694,14 @@ "node_modules/nodemon/node_modules/yallist": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", - "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==" + "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==", + "dev": true }, "node_modules/nopt": { "version": "1.0.10", "resolved": "https://registry.npmjs.org/nopt/-/nopt-1.0.10.tgz", "integrity": "sha512-NWmpvLSqUrgrAC9HCuxEvb+PSloHpqVu+FqcO4eeF2h5qYRhA7ev6KvelyQAKtegUbC6RypJnlEOhd8vloNKYg==", + "dev": true, "dependencies": { "abbrev": "1" }, @@ -3690,6 +3716,7 @@ "version": "3.0.0", "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz", "integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==", + "dev": true, "engines": { "node": ">=0.10.0" } @@ -3890,6 +3917,7 @@ "version": "2.3.1", "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz", "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==", + "dev": true, "engines": { "node": ">=8.6" }, @@ -3972,7 +4000,8 @@ "node_modules/pstree.remy": { "version": "1.1.8", "resolved": "https://registry.npmjs.org/pstree.remy/-/pstree.remy-1.1.8.tgz", - "integrity": "sha512-77DZwxQmxKnu3aR542U+X8FypNzbfJ+C5XQDk3uWjWxn6151aIMGthWYRXTqT1E5oJvg+ljaa2OJi+VfvCOQ8w==" + "integrity": "sha512-77DZwxQmxKnu3aR542U+X8FypNzbfJ+C5XQDk3uWjWxn6151aIMGthWYRXTqT1E5oJvg+ljaa2OJi+VfvCOQ8w==", + "dev": true }, "node_modules/pure-rand": { "version": "6.0.4", @@ -4013,9 +4042,9 @@ } }, "node_modules/raw-body": { - "version": "2.5.1", - "resolved": "https://registry.npmjs.org/raw-body/-/raw-body-2.5.1.tgz", - "integrity": "sha512-qqJBtEyVgS0ZmPGdCFPWJ3FreoqvG4MVQln/kCgF7Olq95IbOp0/BWyMwbdtn4VTvkM8Y7khCQ2Xgk/tcrCXig==", + "version": "2.5.2", + "resolved": "https://registry.npmjs.org/raw-body/-/raw-body-2.5.2.tgz", + "integrity": "sha512-8zGqypfENjCIqGhgXToC8aB2r7YrBX+AQAfIPs/Mlk+BtPTztOvTS01NRW/3Eh60J+a48lt8qsCzirQ6loCVfA==", "dependencies": { "bytes": "3.1.2", "http-errors": "2.0.0", @@ -4036,6 +4065,7 @@ "version": "3.6.0", "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.6.0.tgz", "integrity": "sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA==", + "dev": true, "dependencies": { "picomatch": "^2.2.1" }, @@ -4237,6 +4267,7 @@ "version": "2.0.0", "resolved": "https://registry.npmjs.org/simple-update-notifier/-/simple-update-notifier-2.0.0.tgz", "integrity": "sha512-a2B9Y0KlNXl9u/vsW6sTIu9vGEpfKu2wRV6l1H3XEas/0gUIzGzBoP/IouTcUQbm9JWZLH3COxyn03TYlFax6w==", + "dev": true, "dependencies": { "semver": "^7.5.3" }, @@ -4248,6 +4279,7 @@ "version": "6.0.0", "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz", "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==", + "dev": true, "dependencies": { "yallist": "^4.0.0" }, @@ -4259,6 +4291,7 @@ "version": "7.5.4", "resolved": "https://registry.npmjs.org/semver/-/semver-7.5.4.tgz", "integrity": "sha512-1bCSESV6Pv+i21Hvpxp3Dx+pSD8lIPt8uVjRrxAUt/nbswYc+tK6Y2btiULjd4+fnq15PX+nqQDC7Oft7WkwcA==", + "dev": true, "dependencies": { "lru-cache": "^6.0.0" }, @@ -4272,7 +4305,8 @@ "node_modules/simple-update-notifier/node_modules/yallist": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", - "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==" + "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==", + "dev": true }, "node_modules/sisteransi": { "version": "1.0.5", @@ -4562,6 +4596,7 @@ "version": "5.0.1", "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz", "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==", + "dev": true, "dependencies": { "is-number": "^7.0.0" }, @@ -4581,6 +4616,7 @@ "version": "3.1.0", "resolved": "https://registry.npmjs.org/touch/-/touch-3.1.0.tgz", "integrity": "sha512-WBx8Uy5TLtOSRtIq+M03/sKDrXCLHxwDcquSP2c43Le03/9serjQBIztjRz6FkJez9D/hleyAXTBGLwwZUw9lA==", + "dev": true, "dependencies": { "nopt": "~1.0.10" }, @@ -4624,7 +4660,8 @@ "node_modules/undefsafe": { "version": "2.0.5", "resolved": "https://registry.npmjs.org/undefsafe/-/undefsafe-2.0.5.tgz", - "integrity": "sha512-WxONCrssBM8TSPRqN5EmsjVrsv4A8X12J4ArBiiayv3DyyG3ZlIg6yysuuSYdZsVz3TKcTg2fd//Ujd4CHV1iA==" + "integrity": "sha512-WxONCrssBM8TSPRqN5EmsjVrsv4A8X12J4ArBiiayv3DyyG3ZlIg6yysuuSYdZsVz3TKcTg2fd//Ujd4CHV1iA==", + "dev": true }, "node_modules/undici-types": { "version": "5.26.5", diff --git a/package.json b/package.json index ec6510a..340361f 100644 --- a/package.json +++ b/package.json @@ -20,12 +20,17 @@ "homepage": "https://github.com/boolean-uk/api-address-book#readme", "dependencies": { "cors": "^2.8.5", - "express": "^4.18.2", - "morgan": "^1.10.0", - "nodemon": "^3.0.1" + "express": "^4.19.2", + "morgan": "^1.10.0" }, "devDependencies": { "jest": "^29.7.0", + "nodemon": "^3.1.3", "supertest": "^6.2.3" - } + }, + "directories": { + "doc": "docs", + "test": "test" + }, + "keywords": [] } diff --git a/src/server.js b/src/server.js index 30f0ce3..64c798d 100644 --- a/src/server.js +++ b/src/server.js @@ -1,13 +1,52 @@ -const express = require("express") -const morgan = require("morgan") -const cors = require("cors") -const app = express() +const express = require("express"); +const morgan = require("morgan"); +const cors = require("cors"); +const app = express(); -app.use(morgan("dev")) -app.use(cors()) -app.use(express.json()) +app.use(morgan("dev")); +app.use(cors()); +app.use(express.json()); // write your app code here +const contacts = require("/Users/samisaeed/Boolean/api-express-address-book/data/contacts.js"); -module.exports = app +app.get("/contacts", (req, res) => { + res.json({ + contacts, + }); +}); +app.get("/contacts/:id", (req, res) => { + const contactId = Number(req.params.id); + const findContact = contacts.find((contact) => contact.id === contactId); + res.status(200).json({ contact: findContact }); +}); +app.post("/contacts", (req, res) => { + const contact = req.body; + contact.id = 3; + contacts.push(contact); + res.status(201).json({ contact }); +}); +app.put("/contacts/:id", (req, res) => { + const newContact = req.body; + const contactID = Number(req.params.id); + const foundContact = contacts.find((contact) => contact.id === contactID); + const foundContactIndex = contacts.indexOf(foundContact); + + newContact.id = contactID; + + contacts.splice(foundContactIndex, 1, newContact); + + res.json({ contact: newContact }); +}); +app.delete("/contacts/:id", (req, res) => { + const contactId = Number(req.params.id); + const contactIndex = contacts.findIndex( + (contact) => contact.id === contactId + ); + const deletedContact = contacts[contactIndex]; + contacts.splice(contactIndex, 1); + res.json({ contact: deletedContact }); +}); + +module.exports = app; diff --git a/test/api/standard/contacts.spec.js b/test/api/standard/contacts.spec.js index 4c430a8..4ff2de5 100644 --- a/test/api/standard/contacts.spec.js +++ b/test/api/standard/contacts.spec.js @@ -1,135 +1,129 @@ -const supertest = require('supertest') +const supertest = require("supertest"); -describe('Address Book API', () => { - let app, createTestFormData, updateTestFormData +describe("Address Book API", () => { + let app, createTestFormData, updateTestFormData; beforeEach(() => { - app = require('../../../src/server.js') - createTestFormData = require('../../fixtures/contacts/createTestFormData.js') - updateTestFormData = require('../../fixtures/contacts/updateTestFormData.js') - }) - - describe('GET /contacts', () => { - it('returns default contacts', async () => { - const response = await supertest(app).get('/contacts') - - expect(response.status).toEqual(200) - expect(response.body.contacts).not.toEqual(undefined) - expect(response.body.contacts.length).toEqual(2) - - const [contact1, contact2] = response.body.contacts - expect(contact1.firstName).toEqual("John") - expect(contact1.lastName).toEqual("Carmack") - expect(contact2.firstName).toEqual("Grace") - expect(contact2.lastName).toEqual("Hopper") - }) - }) - - describe('GET /contacts/:id', () => { - it('returns contact, id 2', async () => { - const response = await supertest(app).get('/contacts/2') - - expect(response.status).toEqual(200) - expect(response.body.contact).not.toEqual(undefined) - - const contact = response.body.contact - expect(contact.id).toEqual(2) - expect(contact.firstName).toEqual("Grace") - expect(contact.lastName).toEqual("Hopper") - }) - }) - - describe('POST /contacts', () => { - it('returns created contact', async () => { + app = require("../../../src/server.js"); + createTestFormData = require("../../fixtures/contacts/createTestFormData.js"); + updateTestFormData = require("../../fixtures/contacts/updateTestFormData.js"); + }); + + describe("GET /contacts", () => { + it("returns default contacts", async () => { + const response = await supertest(app).get("/contacts"); + + expect(response.status).toEqual(200); + expect(response.body.contacts).not.toEqual(undefined); + expect(response.body.contacts.length).toEqual(2); + + const [contact1, contact2] = response.body.contacts; + expect(contact1.firstName).toEqual("John"); + expect(contact1.lastName).toEqual("Carmack"); + expect(contact2.firstName).toEqual("Grace"); + expect(contact2.lastName).toEqual("Hopper"); + }); + }); + + describe("GET /contacts/:id", () => { + it("returns contact, id 2", async () => { + const response = await supertest(app).get("/contacts/2"); + + expect(response.status).toEqual(200); + expect(response.body.contact).not.toEqual(undefined); + + const contact = response.body.contact; + expect(contact.id).toEqual(2); + expect(contact.firstName).toEqual("Grace"); + expect(contact.lastName).toEqual("Hopper"); + }); + }); + + describe("POST /contacts", () => { + it("returns created contact", async () => { const response = await supertest(app) - .post('/contacts') - .send(createTestFormData) + .post("/contacts") + .send(createTestFormData); - expect(response.status).toEqual(201) - expect(response.body.contact).not.toEqual(undefined) + expect(response.status).toEqual(201); + expect(response.body.contact).not.toEqual(undefined); - const contact = response.body.contact - expect(contact.id).toEqual(3) - expect(contact.firstName).toEqual(createTestFormData.firstName) - expect(contact.lastName).toEqual(createTestFormData.lastName) - }) + const contact = response.body.contact; + expect(contact.id).toEqual(3); + expect(contact.firstName).toEqual(createTestFormData.firstName); + expect(contact.lastName).toEqual(createTestFormData.lastName); + }); - it('adds contact to data store', async () => { - await supertest(app) - .post('/contacts') - .send(createTestFormData) + it("adds contact to data store", async () => { + await supertest(app).post("/contacts").send(createTestFormData); - const response = await supertest(app).get('/contacts') + const response = await supertest(app).get("/contacts"); - expect(response.status).toEqual(200) - expect(response.body.contacts).not.toEqual(undefined) - expect(response.body.contacts.length).toEqual(3) + expect(response.status).toEqual(200); + expect(response.body.contacts).not.toEqual(undefined); + expect(response.body.contacts.length).toEqual(3); - const [contact1, contact2, contact3] = response.body.contacts - expect(contact3.firstName).toEqual(createTestFormData.firstName) - expect(contact3.lastName).toEqual(createTestFormData.lastName) - }) - }) + const [contact1, contact2, contact3] = response.body.contacts; + expect(contact3.firstName).toEqual(createTestFormData.firstName); + expect(contact3.lastName).toEqual(createTestFormData.lastName); + }); + }); - describe('PUT /contacts', () => { - let updatedContact + describe("PUT /contacts", () => { + let updatedContact; beforeEach(() => { updatedContact = { ...updateTestFormData, - id: 1 - } - }) - it('returns updated contact', async () => { + id: 1, + }; + }); + it("returns updated contact", async () => { const response = await supertest(app) .put(`/contacts/1`) - .send(updateTestFormData) + .send(updateTestFormData); - expect(response.status).toEqual(200) - expect(response.body.contact).not.toEqual(undefined) + expect(response.status).toEqual(200); + expect(response.body.contact).not.toEqual(undefined); - const contact = response.body.contact - expect(contact).toMatchObject(updatedContact) - }) + const contact = response.body.contact; + expect(contact).toMatchObject(updatedContact); + }); - it('updated contact is in data store', async () => { - await supertest(app) - .put(`/contacts/1`) - .send(updateTestFormData) + it("updated contact is in data store", async () => { + await supertest(app).put(`/contacts/1`).send(updateTestFormData); - const response = await supertest(app).get('/contacts') + const response = await supertest(app).get("/contacts"); - expect(response.status).toEqual(200) - expect(response.body.contacts).not.toEqual(undefined) - expect(response.body.contacts.length).toEqual(2) + expect(response.status).toEqual(200); + expect(response.body.contacts).not.toEqual(undefined); + expect(response.body.contacts.length).toEqual(2); - const [contact1, contact2] = response.body.contacts - expect(contact1.firstName).toEqual(updatedContact.firstName) - expect(contact1.lastName).toEqual(updatedContact.lastName) - }) - }) + const [contact1, contact2] = response.body.contacts; + expect(contact1.firstName).toEqual(updatedContact.firstName); + expect(contact1.lastName).toEqual(updatedContact.lastName); + }); + }); - describe('DELETE /contacts', () => { - it('returns deleted contact', async () => { - const response = await supertest(app) - .delete(`/contacts/1`) + describe("DELETE /contacts", () => { + it("returns deleted contact", async () => { + const response = await supertest(app).delete(`/contacts/1`); - expect(response.status).toEqual(200) - expect(response.body.contact).not.toEqual(undefined) - expect(response.body.contact.id).toEqual(1) - }) + expect(response.status).toEqual(200); + expect(response.body.contact).not.toEqual(undefined); + expect(response.body.contact.id).toEqual(1); + }); - it('removes contact from data store', async () => { - const response = await supertest(app) - .delete(`/contacts/1`) + it("removes contact from data store", async () => { + const response = await supertest(app).delete(`/contacts/1`); - const deletedContact = response.body.contact + const deletedContact = response.body.contact; - const response2 = await supertest(app).get('/contacts') + const response2 = await supertest(app).get("/contacts"); - expect(response2.status).toEqual(200) - expect(response2.body.contacts).not.toEqual(undefined) - expect(response2.body.contacts.length).toEqual(1) - expect(response2.body.contacts).not.toContain(deletedContact) - }) - }) -}) + expect(response2.status).toEqual(200); + expect(response2.body.contacts).not.toEqual(undefined); + expect(response2.body.contacts.length).toEqual(1); + expect(response2.body.contacts).not.toContain(deletedContact); + }); + }); +}); From 31107ed18cacfdce23581cfba2e728f1df87199c Mon Sep 17 00:00:00 2001 From: samisalehsaeed Date: Mon, 17 Jun 2024 16:54:42 +0100 Subject: [PATCH 2/3] Sami Saeed --- data/contacts.js | 42 +++++++++++++++++++++--------------------- package-lock.json | 14 +++++++------- 2 files changed, 28 insertions(+), 28 deletions(-) diff --git a/data/contacts.js b/data/contacts.js index 0f5157f..cea566f 100644 --- a/data/contacts.js +++ b/data/contacts.js @@ -1,26 +1,26 @@ const contacts = [ { - "id": 1, - "firstName": "John", - "lastName": "Carmack", - "street": "10 Keen Street", - "city": "London", - "type": "work", - "email": "test@test.com", - "linkedin": "https://www.linkedin.com/school/boolean-uk/", - "twitter": "https://twitter.com/booleanuk" + id: 1, + firstName: "John", + lastName: "Carmack", + street: "10 Keen Street", + city: "London", + type: "work", + email: "test@test.com", + linkedin: "https://www.linkedin.com/school/boolean-uk/", + twitter: "https://twitter.com/booleanuk", }, { - "id": 2, - "firstName": "Grace", - "lastName": "Hopper", - "street": "32 Deebug Road", - "city": "London", - "type": "personal", - "email": "test@test.com", - "linkedin": "https://www.linkedin.com/school/boolean-uk/", - "twitter": "https://twitter.com/booleanuk" - } -] + id: 2, + firstName: "Grace", + lastName: "Hopper", + street: "32 Deebug Road", + city: "London", + type: "personal", + email: "test@test.com", + linkedin: "https://www.linkedin.com/school/boolean-uk/", + twitter: "https://twitter.com/booleanuk", + }, +]; -module.exports = contacts +module.exports = contacts; diff --git a/package-lock.json b/package-lock.json index dee22db..888489d 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1447,12 +1447,12 @@ } }, "node_modules/braces": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.2.tgz", - "integrity": "sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==", + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.3.tgz", + "integrity": "sha512-yQbXgO/OSZVD2IsiLlro+7Hf6Q18EJrKSEsdoMzKePKXct3gvD8oLcOQdIzGupr5Fj+EDe8gO/lxc1BzfMpxvA==", "dev": true, "dependencies": { - "fill-range": "^7.0.1" + "fill-range": "^7.1.1" }, "engines": { "node": ">=8" @@ -2102,9 +2102,9 @@ } }, "node_modules/fill-range": { - "version": "7.0.1", - "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz", - "integrity": "sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==", + "version": "7.1.1", + "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.1.1.tgz", + "integrity": "sha512-YsGpe3WHLK8ZYi4tWDg2Jy3ebRz2rXowDxnld4bkQB00cc/1Zw9AWnC0i9ztDJitivtQvaI9KaLyKrc+hBW0yg==", "dev": true, "dependencies": { "to-regex-range": "^5.0.1" From acc5495a27bfee42ff50ffc51a42bbb708e7e729 Mon Sep 17 00:00:00 2001 From: samisalehsaeed Date: Mon, 17 Jun 2024 17:03:17 +0100 Subject: [PATCH 3/3] Sami Saeed --- src/server.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/server.js b/src/server.js index 64c798d..f359249 100644 --- a/src/server.js +++ b/src/server.js @@ -9,7 +9,7 @@ app.use(express.json()); // write your app code here -const contacts = require("/Users/samisaeed/Boolean/api-express-address-book/data/contacts.js"); +const contacts = require("../data/contacts.js"); app.get("/contacts", (req, res) => { res.json({