From f02ebf3d1311ef49e98a9a5e4a32556e0575eb06 Mon Sep 17 00:00:00 2001 From: Maick Speck Date: Mon, 13 Jun 2022 21:31:41 -0300 Subject: [PATCH 01/16] mongodb server --- config/yaml/values.yaml | 3 + package-lock.json | 388 +++++++++++++++++- package.json | 2 + src/app.module.ts | 9 + .../controller/neighborhoods.controller.ts | 8 + .../adapter/neighborhoods.module.ts | 14 +- .../neighborhoods-mongoose.repository.ts | 19 + .../{ => puppeteer}/guia-mais.repository.ts | 10 +- .../adapter/service/neighborhoods.service.ts | 10 +- .../domain/schemas/neighborhood.schema.ts | 12 + .../guia-mais.repository.spec.ts | 6 +- 11 files changed, 462 insertions(+), 19 deletions(-) create mode 100644 src/microservice/adapter/repository/neighborhoods/neighborhoods-mongoose.repository.ts rename src/microservice/adapter/repository/neighborhoods/{ => puppeteer}/guia-mais.repository.ts (67%) create mode 100644 src/microservice/domain/schemas/neighborhood.schema.ts rename test/unit/microservice/adapter/repository/neighborhoods/{ => puppeteer}/guia-mais.repository.spec.ts (86%) diff --git a/config/yaml/values.yaml b/config/yaml/values.yaml index 02fb75f..6640751 100644 --- a/config/yaml/values.yaml +++ b/config/yaml/values.yaml @@ -2,5 +2,8 @@ repository: neighborhoods: guia-mais: url: 'https://www.guiamais.com.br/bairros' +database: + mongodb: + connection: 'mongodb+srv://dev-seeder-root:hpYpxyjrKExNQviu@devseeder.v6xtv.mongodb.net/places' api: port: 3000 diff --git a/package-lock.json b/package-lock.json index dd62aeb..c8407d9 100644 --- a/package-lock.json +++ b/package-lock.json @@ -13,6 +13,7 @@ "@nestjs/common": "^8.0.0", "@nestjs/config": "^2.0.1", "@nestjs/core": "^8.0.0", + "@nestjs/mongoose": "^9.1.0", "@nestjs/platform-express": "^8.0.0", "chai": "^4.3.6", "cheerio": "^1.0.0-rc.10", @@ -21,6 +22,7 @@ "dotenv": "^16.0.1", "fs": "^0.0.1-security", "js-yaml": "^4.1.0", + "mongoose": "^6.3.8", "nest-puppeteer": "^1.1.1", "puppeteer": "^14.1.0", "reflect-metadata": "^0.1.13", @@ -1465,6 +1467,18 @@ } } }, + "node_modules/@nestjs/mongoose": { + "version": "9.1.0", + "resolved": "https://registry.npmjs.org/@nestjs/mongoose/-/mongoose-9.1.0.tgz", + "integrity": "sha512-tkd5ZD7UYreHv/OaEcdgbsiwywmXuAwzcD3u/kGAGE8c4dyutkc09LxNGsp9q0+NdV0EK3NauICNLWspF7S+wA==", + "peerDependencies": { + "@nestjs/common": "^6.0.0 || ^7.0.0 || ^8.0.0", + "@nestjs/core": "^6.0.0 || ^7.0.0 || ^8.0.0", + "mongoose": "^6.0.2", + "reflect-metadata": "^0.1.12", + "rxjs": "^6.0.0 || ^7.0.0" + } + }, "node_modules/@nestjs/platform-express": { "version": "8.4.5", "resolved": "https://registry.npmjs.org/@nestjs/platform-express/-/platform-express-8.4.5.tgz", @@ -1845,8 +1859,7 @@ "node_modules/@types/node": { "version": "16.11.36", "resolved": "https://registry.npmjs.org/@types/node/-/node-16.11.36.tgz", - "integrity": "sha512-FR5QJe+TaoZ2GsMHkjuwoNabr+UrJNRr2HNOo+r/7vhcuntM6Ee/pRPOnRhhL2XE9OOvX9VLEq+BcXl3VjNoWA==", - "devOptional": true + "integrity": "sha512-FR5QJe+TaoZ2GsMHkjuwoNabr+UrJNRr2HNOo+r/7vhcuntM6Ee/pRPOnRhhL2XE9OOvX9VLEq+BcXl3VjNoWA==" }, "node_modules/@types/parse-json": { "version": "4.0.0", @@ -1916,6 +1929,20 @@ "@types/superagent": "*" } }, + "node_modules/@types/webidl-conversions": { + "version": "6.1.1", + "resolved": "https://registry.npmjs.org/@types/webidl-conversions/-/webidl-conversions-6.1.1.tgz", + "integrity": "sha512-XAahCdThVuCFDQLT7R7Pk/vqeObFNL3YqRyFZg+AqAP/W1/w3xHaIxuW7WszQqTbIBOPRcItYJIou3i/mppu3Q==" + }, + "node_modules/@types/whatwg-url": { + "version": "8.2.1", + "resolved": "https://registry.npmjs.org/@types/whatwg-url/-/whatwg-url-8.2.1.tgz", + "integrity": "sha512-2YubE1sjj5ifxievI5Ge1sckb9k/Er66HyR2c+3+I6VDUUg1TLPdYYTEbQ+DjRkS4nTxMJhgWfSfMRD2sl2EYQ==", + "dependencies": { + "@types/node": "*", + "@types/webidl-conversions": "*" + } + }, "node_modules/@types/yargs": { "version": "16.0.4", "resolved": "https://registry.npmjs.org/@types/yargs/-/yargs-16.0.4.tgz", @@ -2824,6 +2851,17 @@ "node-int64": "^0.4.0" } }, + "node_modules/bson": { + "version": "4.6.4", + "resolved": "https://registry.npmjs.org/bson/-/bson-4.6.4.tgz", + "integrity": "sha512-TdQ3FzguAu5HKPPlr0kYQCyrYUYh8tFM+CMTpxjNzVzxeiJY00Rtuj3LXLHSgiGvmaWlZ8PE+4KyM2thqE38pQ==", + "dependencies": { + "buffer": "^5.6.0" + }, + "engines": { + "node": ">=6.9.0" + } + }, "node_modules/buffer": { "version": "5.7.1", "resolved": "https://registry.npmjs.org/buffer/-/buffer-5.7.1.tgz", @@ -3512,6 +3550,14 @@ "node": ">=0.4.0" } }, + "node_modules/denque": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/denque/-/denque-2.0.1.tgz", + "integrity": "sha512-tfiWc6BQLXNLpNiR5iGd0Ocu3P3VpxfzFiqubLgMfhfOw9WyvgJBd46CClNn9k3qfbjvT//0cf7AlYRX/OslMQ==", + "engines": { + "node": ">=0.10" + } + }, "node_modules/depd": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/depd/-/depd-2.0.0.tgz", @@ -5146,6 +5192,11 @@ "node": ">= 0.10" } }, + "node_modules/ip": { + "version": "1.1.8", + "resolved": "https://registry.npmjs.org/ip/-/ip-1.1.8.tgz", + "integrity": "sha512-PuExPYUiu6qMBQb4l06ecm6T6ujzhmh+MeJcW9wa89PoAz5pvd4zPgN5WJV104mb6S2T1AwNIAaB70JNrLQWhg==" + }, "node_modules/ipaddr.js": { "version": "1.9.1", "resolved": "https://registry.npmjs.org/ipaddr.js/-/ipaddr.js-1.9.1.tgz", @@ -6381,6 +6432,11 @@ "resolved": "https://registry.npmjs.org/just-extend/-/just-extend-4.2.1.tgz", "integrity": "sha512-g3UB796vUFIY90VIv/WX3L2c8CS2MdWUww3CNrYmqza1Fg0DURc2K/O4YrnklBdQarSJ/y8JnJYDGc+1iumQjg==" }, + "node_modules/kareem": { + "version": "2.3.5", + "resolved": "https://registry.npmjs.org/kareem/-/kareem-2.3.5.tgz", + "integrity": "sha512-qxCyQtp3ioawkiRNQr/v8xw9KIviMSSNmy+63Wubj7KmMn3g7noRXIZB4vPCAP+ETi2SR8eH6CvmlKZuGpoHOg==" + }, "node_modules/kleur": { "version": "3.0.3", "resolved": "https://registry.npmjs.org/kleur/-/kleur-3.0.3.tgz", @@ -6602,6 +6658,12 @@ "node": ">= 4.0.0" } }, + "node_modules/memory-pager": { + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/memory-pager/-/memory-pager-1.5.0.tgz", + "integrity": "sha512-ZS4Bp4r/Zoeq6+NLJpP+0Zzm0pR8whtGPf1XExKLJBAczGMnSi3It14OiNCStjQjM6NU1okjQGSxgEZN8eBYKg==", + "optional": true + }, "node_modules/merge-descriptors": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/merge-descriptors/-/merge-descriptors-1.0.1.tgz", @@ -6714,6 +6776,108 @@ "resolved": "https://registry.npmjs.org/mkdirp-classic/-/mkdirp-classic-0.5.3.tgz", "integrity": "sha512-gKLcREMhtuZRwRAfqP3RFW+TK4JqApVBtOIftVgjuABpAtpxhPGaDcfvbhNvD0B8iD1oUr/txX35NjcaY6Ns/A==" }, + "node_modules/mongodb": { + "version": "4.5.0", + "resolved": "https://registry.npmjs.org/mongodb/-/mongodb-4.5.0.tgz", + "integrity": "sha512-A2l8MjEpKojnhbCM0MK3+UOGUSGvTNNSv7AkP1fsT7tkambrkkqN/5F2y+PhzsV0Nbv58u04TETpkaSEdI2zKA==", + "dependencies": { + "bson": "^4.6.2", + "denque": "^2.0.1", + "mongodb-connection-string-url": "^2.5.2", + "socks": "^2.6.2" + }, + "engines": { + "node": ">=12.9.0" + }, + "optionalDependencies": { + "saslprep": "^1.0.3" + } + }, + "node_modules/mongodb-connection-string-url": { + "version": "2.5.2", + "resolved": "https://registry.npmjs.org/mongodb-connection-string-url/-/mongodb-connection-string-url-2.5.2.tgz", + "integrity": "sha512-tWDyIG8cQlI5k3skB6ywaEA5F9f5OntrKKsT/Lteub2zgwSUlhqEN2inGgBTm8bpYJf8QYBdA/5naz65XDpczA==", + "dependencies": { + "@types/whatwg-url": "^8.2.1", + "whatwg-url": "^11.0.0" + } + }, + "node_modules/mongodb-connection-string-url/node_modules/tr46": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/tr46/-/tr46-3.0.0.tgz", + "integrity": "sha512-l7FvfAHlcmulp8kr+flpQZmVwtu7nfRV7NZujtN0OqES8EL4O4e0qqzL0DC5gAvx/ZC/9lk6rhcUwYvkBnBnYA==", + "dependencies": { + "punycode": "^2.1.1" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/mongodb-connection-string-url/node_modules/webidl-conversions": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-7.0.0.tgz", + "integrity": "sha512-VwddBukDzu71offAQR975unBIGqfKZpM+8ZX6ySk8nYhVoo5CYaZyzt3YBvYtRtO+aoGlqxPg/B87NGVZ/fu6g==", + "engines": { + "node": ">=12" + } + }, + "node_modules/mongodb-connection-string-url/node_modules/whatwg-url": { + "version": "11.0.0", + "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-11.0.0.tgz", + "integrity": "sha512-RKT8HExMpoYx4igMiVMY83lN6UeITKJlBQ+vR/8ZJ8OCdSiN3RwCq+9gH0+Xzj0+5IrM6i4j/6LuvzbZIQgEcQ==", + "dependencies": { + "tr46": "^3.0.0", + "webidl-conversions": "^7.0.0" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/mongoose": { + "version": "6.3.8", + "resolved": "https://registry.npmjs.org/mongoose/-/mongoose-6.3.8.tgz", + "integrity": "sha512-TPIm61/DR2Go+aDXD5HM6vwMvl4dEOFos1oTT4yPT8qJpcTugxWXf5J2Vp+0vzqDETfDMtN/gBhPCzFdFJx2bg==", + "dependencies": { + "bson": "^4.6.2", + "kareem": "2.3.5", + "mongodb": "4.5.0", + "mpath": "0.9.0", + "mquery": "4.0.3", + "ms": "2.1.3", + "sift": "16.0.0" + }, + "engines": { + "node": ">=12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/mongoose" + } + }, + "node_modules/mongoose/node_modules/ms": { + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", + "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==" + }, + "node_modules/mpath": { + "version": "0.9.0", + "resolved": "https://registry.npmjs.org/mpath/-/mpath-0.9.0.tgz", + "integrity": "sha512-ikJRQTk8hw5DEoFVxHG1Gn9T/xcjtdnOKIU1JTmGjZZlg9LST2mBLmcX3/ICIbgJydT2GOc15RnNy5mHmzfSew==", + "engines": { + "node": ">=4.0.0" + } + }, + "node_modules/mquery": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/mquery/-/mquery-4.0.3.tgz", + "integrity": "sha512-J5heI+P08I6VJ2Ky3+33IpCdAvlYGTSUjwTPxkAr8i8EoduPMBX2OY/wa3IKZIQl7MU4SbFk8ndgSKyB/cl1zA==", + "dependencies": { + "debug": "4.x" + }, + "engines": { + "node": ">=12.0.0" + } + }, "node_modules/ms": { "version": "2.1.2", "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", @@ -7362,7 +7526,6 @@ "version": "2.1.1", "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.1.1.tgz", "integrity": "sha512-XRsRjdf+j5ml+y/6GKHPZbrF/8p2Yga0JPtdqTIY2Xe5ohJPD9saDJJLPvp9+NSBprVvevdXZybnj2cv8OEd0A==", - "dev": true, "engines": { "node": ">=6" } @@ -7708,6 +7871,18 @@ "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==" }, + "node_modules/saslprep": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/saslprep/-/saslprep-1.0.3.tgz", + "integrity": "sha512-/MY/PEMbk2SuY5sScONwhUDsV2p77Znkb/q3nSVstq/yQzYJOH/Azh29p9oJLsl3LnQwSvZDKagDGBsBwSooag==", + "optional": true, + "dependencies": { + "sparse-bitfield": "^3.0.3" + }, + "engines": { + "node": ">=6" + } + }, "node_modules/saxes": { "version": "5.0.1", "resolved": "https://registry.npmjs.org/saxes/-/saxes-5.0.1.tgz", @@ -7903,6 +8078,11 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/sift": { + "version": "16.0.0", + "resolved": "https://registry.npmjs.org/sift/-/sift-16.0.0.tgz", + "integrity": "sha512-ILTjdP2Mv9V1kIxWMXeMTIRbOBrqKc4JAXmFMnFq3fKeyQ2Qwa3Dw1ubcye3vR+Y6ofA0b9gNDr/y2t6eUeIzQ==" + }, "node_modules/signal-exit": { "version": "3.0.7", "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.7.tgz", @@ -7949,6 +8129,28 @@ "node": ">=8" } }, + "node_modules/smart-buffer": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/smart-buffer/-/smart-buffer-4.2.0.tgz", + "integrity": "sha512-94hK0Hh8rPqQl2xXc3HsaBoOXKV20MToPkcXvwbISWLEs+64sBq5kFgn2kJDHb1Pry9yrP0dxrCI9RRci7RXKg==", + "engines": { + "node": ">= 6.0.0", + "npm": ">= 3.0.0" + } + }, + "node_modules/socks": { + "version": "2.6.2", + "resolved": "https://registry.npmjs.org/socks/-/socks-2.6.2.tgz", + "integrity": "sha512-zDZhHhZRY9PxRruRMR7kMhnf3I8hDs4S3f9RecfnGxvcBHQcKcIH/oUcEWffsfl1XxdYlA7nnlGbbTvPz9D8gA==", + "dependencies": { + "ip": "^1.1.5", + "smart-buffer": "^4.2.0" + }, + "engines": { + "node": ">= 10.13.0", + "npm": ">= 3.0.0" + } + }, "node_modules/source-map": { "version": "0.7.3", "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.7.3.tgz", @@ -7983,6 +8185,15 @@ "integrity": "sha512-9NykojV5Uih4lgo5So5dtw+f0JgJX30KCNI8gwhz2J9A15wD0Ml6tjHKwf6fTSa6fAdVBdZeNOs9eJ71qCk8vA==", "dev": true }, + "node_modules/sparse-bitfield": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/sparse-bitfield/-/sparse-bitfield-3.0.3.tgz", + "integrity": "sha512-kvzhi7vqKTfkh0PZU+2D2PIllw2ymqJKujUcyPMd9Y75Nv4nPbGJZXNhxsgdQab2BmlDct1YnfQCguEvHr7VsQ==", + "optional": true, + "dependencies": { + "memory-pager": "^1.0.2" + } + }, "node_modules/sprintf-js": { "version": "1.0.3", "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz", @@ -10363,6 +10574,12 @@ "uuid": "8.3.2" } }, + "@nestjs/mongoose": { + "version": "9.1.0", + "resolved": "https://registry.npmjs.org/@nestjs/mongoose/-/mongoose-9.1.0.tgz", + "integrity": "sha512-tkd5ZD7UYreHv/OaEcdgbsiwywmXuAwzcD3u/kGAGE8c4dyutkc09LxNGsp9q0+NdV0EK3NauICNLWspF7S+wA==", + "requires": {} + }, "@nestjs/platform-express": { "version": "8.4.5", "resolved": "https://registry.npmjs.org/@nestjs/platform-express/-/platform-express-8.4.5.tgz", @@ -10691,8 +10908,7 @@ "@types/node": { "version": "16.11.36", "resolved": "https://registry.npmjs.org/@types/node/-/node-16.11.36.tgz", - "integrity": "sha512-FR5QJe+TaoZ2GsMHkjuwoNabr+UrJNRr2HNOo+r/7vhcuntM6Ee/pRPOnRhhL2XE9OOvX9VLEq+BcXl3VjNoWA==", - "devOptional": true + "integrity": "sha512-FR5QJe+TaoZ2GsMHkjuwoNabr+UrJNRr2HNOo+r/7vhcuntM6Ee/pRPOnRhhL2XE9OOvX9VLEq+BcXl3VjNoWA==" }, "@types/parse-json": { "version": "4.0.0", @@ -10762,6 +10978,20 @@ "@types/superagent": "*" } }, + "@types/webidl-conversions": { + "version": "6.1.1", + "resolved": "https://registry.npmjs.org/@types/webidl-conversions/-/webidl-conversions-6.1.1.tgz", + "integrity": "sha512-XAahCdThVuCFDQLT7R7Pk/vqeObFNL3YqRyFZg+AqAP/W1/w3xHaIxuW7WszQqTbIBOPRcItYJIou3i/mppu3Q==" + }, + "@types/whatwg-url": { + "version": "8.2.1", + "resolved": "https://registry.npmjs.org/@types/whatwg-url/-/whatwg-url-8.2.1.tgz", + "integrity": "sha512-2YubE1sjj5ifxievI5Ge1sckb9k/Er66HyR2c+3+I6VDUUg1TLPdYYTEbQ+DjRkS4nTxMJhgWfSfMRD2sl2EYQ==", + "requires": { + "@types/node": "*", + "@types/webidl-conversions": "*" + } + }, "@types/yargs": { "version": "16.0.4", "resolved": "https://registry.npmjs.org/@types/yargs/-/yargs-16.0.4.tgz", @@ -11448,6 +11678,14 @@ "node-int64": "^0.4.0" } }, + "bson": { + "version": "4.6.4", + "resolved": "https://registry.npmjs.org/bson/-/bson-4.6.4.tgz", + "integrity": "sha512-TdQ3FzguAu5HKPPlr0kYQCyrYUYh8tFM+CMTpxjNzVzxeiJY00Rtuj3LXLHSgiGvmaWlZ8PE+4KyM2thqE38pQ==", + "requires": { + "buffer": "^5.6.0" + } + }, "buffer": { "version": "5.7.1", "resolved": "https://registry.npmjs.org/buffer/-/buffer-5.7.1.tgz", @@ -11979,6 +12217,11 @@ "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz", "integrity": "sha1-3zrhmayt+31ECqrgsp4icrJOxhk=" }, + "denque": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/denque/-/denque-2.0.1.tgz", + "integrity": "sha512-tfiWc6BQLXNLpNiR5iGd0Ocu3P3VpxfzFiqubLgMfhfOw9WyvgJBd46CClNn9k3qfbjvT//0cf7AlYRX/OslMQ==" + }, "depd": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/depd/-/depd-2.0.0.tgz", @@ -13180,6 +13423,11 @@ "integrity": "sha512-agE4QfB2Lkp9uICn7BAqoscw4SZP9kTE2hxiFI3jBPmXJfdqiahTbUuKGsMoN2GtqL9AxhYioAcVvgsb1HvRbA==", "dev": true }, + "ip": { + "version": "1.1.8", + "resolved": "https://registry.npmjs.org/ip/-/ip-1.1.8.tgz", + "integrity": "sha512-PuExPYUiu6qMBQb4l06ecm6T6ujzhmh+MeJcW9wa89PoAz5pvd4zPgN5WJV104mb6S2T1AwNIAaB70JNrLQWhg==" + }, "ipaddr.js": { "version": "1.9.1", "resolved": "https://registry.npmjs.org/ipaddr.js/-/ipaddr.js-1.9.1.tgz", @@ -14131,6 +14379,11 @@ "resolved": "https://registry.npmjs.org/just-extend/-/just-extend-4.2.1.tgz", "integrity": "sha512-g3UB796vUFIY90VIv/WX3L2c8CS2MdWUww3CNrYmqza1Fg0DURc2K/O4YrnklBdQarSJ/y8JnJYDGc+1iumQjg==" }, + "kareem": { + "version": "2.3.5", + "resolved": "https://registry.npmjs.org/kareem/-/kareem-2.3.5.tgz", + "integrity": "sha512-qxCyQtp3ioawkiRNQr/v8xw9KIviMSSNmy+63Wubj7KmMn3g7noRXIZB4vPCAP+ETi2SR8eH6CvmlKZuGpoHOg==" + }, "kleur": { "version": "3.0.3", "resolved": "https://registry.npmjs.org/kleur/-/kleur-3.0.3.tgz", @@ -14305,6 +14558,12 @@ "fs-monkey": "1.0.3" } }, + "memory-pager": { + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/memory-pager/-/memory-pager-1.5.0.tgz", + "integrity": "sha512-ZS4Bp4r/Zoeq6+NLJpP+0Zzm0pR8whtGPf1XExKLJBAczGMnSi3It14OiNCStjQjM6NU1okjQGSxgEZN8eBYKg==", + "optional": true + }, "merge-descriptors": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/merge-descriptors/-/merge-descriptors-1.0.1.tgz", @@ -14387,6 +14646,85 @@ "resolved": "https://registry.npmjs.org/mkdirp-classic/-/mkdirp-classic-0.5.3.tgz", "integrity": "sha512-gKLcREMhtuZRwRAfqP3RFW+TK4JqApVBtOIftVgjuABpAtpxhPGaDcfvbhNvD0B8iD1oUr/txX35NjcaY6Ns/A==" }, + "mongodb": { + "version": "4.5.0", + "resolved": "https://registry.npmjs.org/mongodb/-/mongodb-4.5.0.tgz", + "integrity": "sha512-A2l8MjEpKojnhbCM0MK3+UOGUSGvTNNSv7AkP1fsT7tkambrkkqN/5F2y+PhzsV0Nbv58u04TETpkaSEdI2zKA==", + "requires": { + "bson": "^4.6.2", + "denque": "^2.0.1", + "mongodb-connection-string-url": "^2.5.2", + "saslprep": "^1.0.3", + "socks": "^2.6.2" + } + }, + "mongodb-connection-string-url": { + "version": "2.5.2", + "resolved": "https://registry.npmjs.org/mongodb-connection-string-url/-/mongodb-connection-string-url-2.5.2.tgz", + "integrity": "sha512-tWDyIG8cQlI5k3skB6ywaEA5F9f5OntrKKsT/Lteub2zgwSUlhqEN2inGgBTm8bpYJf8QYBdA/5naz65XDpczA==", + "requires": { + "@types/whatwg-url": "^8.2.1", + "whatwg-url": "^11.0.0" + }, + "dependencies": { + "tr46": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/tr46/-/tr46-3.0.0.tgz", + "integrity": "sha512-l7FvfAHlcmulp8kr+flpQZmVwtu7nfRV7NZujtN0OqES8EL4O4e0qqzL0DC5gAvx/ZC/9lk6rhcUwYvkBnBnYA==", + "requires": { + "punycode": "^2.1.1" + } + }, + "webidl-conversions": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-7.0.0.tgz", + "integrity": "sha512-VwddBukDzu71offAQR975unBIGqfKZpM+8ZX6ySk8nYhVoo5CYaZyzt3YBvYtRtO+aoGlqxPg/B87NGVZ/fu6g==" + }, + "whatwg-url": { + "version": "11.0.0", + "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-11.0.0.tgz", + "integrity": "sha512-RKT8HExMpoYx4igMiVMY83lN6UeITKJlBQ+vR/8ZJ8OCdSiN3RwCq+9gH0+Xzj0+5IrM6i4j/6LuvzbZIQgEcQ==", + "requires": { + "tr46": "^3.0.0", + "webidl-conversions": "^7.0.0" + } + } + } + }, + "mongoose": { + "version": "6.3.8", + "resolved": "https://registry.npmjs.org/mongoose/-/mongoose-6.3.8.tgz", + "integrity": "sha512-TPIm61/DR2Go+aDXD5HM6vwMvl4dEOFos1oTT4yPT8qJpcTugxWXf5J2Vp+0vzqDETfDMtN/gBhPCzFdFJx2bg==", + "requires": { + "bson": "^4.6.2", + "kareem": "2.3.5", + "mongodb": "4.5.0", + "mpath": "0.9.0", + "mquery": "4.0.3", + "ms": "2.1.3", + "sift": "16.0.0" + }, + "dependencies": { + "ms": { + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", + "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==" + } + } + }, + "mpath": { + "version": "0.9.0", + "resolved": "https://registry.npmjs.org/mpath/-/mpath-0.9.0.tgz", + "integrity": "sha512-ikJRQTk8hw5DEoFVxHG1Gn9T/xcjtdnOKIU1JTmGjZZlg9LST2mBLmcX3/ICIbgJydT2GOc15RnNy5mHmzfSew==" + }, + "mquery": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/mquery/-/mquery-4.0.3.tgz", + "integrity": "sha512-J5heI+P08I6VJ2Ky3+33IpCdAvlYGTSUjwTPxkAr8i8EoduPMBX2OY/wa3IKZIQl7MU4SbFk8ndgSKyB/cl1zA==", + "requires": { + "debug": "4.x" + } + }, "ms": { "version": "2.1.2", "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", @@ -14873,8 +15211,7 @@ "punycode": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.1.1.tgz", - "integrity": "sha512-XRsRjdf+j5ml+y/6GKHPZbrF/8p2Yga0JPtdqTIY2Xe5ohJPD9saDJJLPvp9+NSBprVvevdXZybnj2cv8OEd0A==", - "dev": true + "integrity": "sha512-XRsRjdf+j5ml+y/6GKHPZbrF/8p2Yga0JPtdqTIY2Xe5ohJPD9saDJJLPvp9+NSBprVvevdXZybnj2cv8OEd0A==" }, "puppeteer": { "version": "14.1.1", @@ -15097,6 +15434,15 @@ "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==" }, + "saslprep": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/saslprep/-/saslprep-1.0.3.tgz", + "integrity": "sha512-/MY/PEMbk2SuY5sScONwhUDsV2p77Znkb/q3nSVstq/yQzYJOH/Azh29p9oJLsl3LnQwSvZDKagDGBsBwSooag==", + "optional": true, + "requires": { + "sparse-bitfield": "^3.0.3" + } + }, "saxes": { "version": "5.0.1", "resolved": "https://registry.npmjs.org/saxes/-/saxes-5.0.1.tgz", @@ -15255,6 +15601,11 @@ "object-inspect": "^1.9.0" } }, + "sift": { + "version": "16.0.0", + "resolved": "https://registry.npmjs.org/sift/-/sift-16.0.0.tgz", + "integrity": "sha512-ILTjdP2Mv9V1kIxWMXeMTIRbOBrqKc4JAXmFMnFq3fKeyQ2Qwa3Dw1ubcye3vR+Y6ofA0b9gNDr/y2t6eUeIzQ==" + }, "signal-exit": { "version": "3.0.7", "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.7.tgz", @@ -15296,6 +15647,20 @@ "integrity": "sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==", "dev": true }, + "smart-buffer": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/smart-buffer/-/smart-buffer-4.2.0.tgz", + "integrity": "sha512-94hK0Hh8rPqQl2xXc3HsaBoOXKV20MToPkcXvwbISWLEs+64sBq5kFgn2kJDHb1Pry9yrP0dxrCI9RRci7RXKg==" + }, + "socks": { + "version": "2.6.2", + "resolved": "https://registry.npmjs.org/socks/-/socks-2.6.2.tgz", + "integrity": "sha512-zDZhHhZRY9PxRruRMR7kMhnf3I8hDs4S3f9RecfnGxvcBHQcKcIH/oUcEWffsfl1XxdYlA7nnlGbbTvPz9D8gA==", + "requires": { + "ip": "^1.1.5", + "smart-buffer": "^4.2.0" + } + }, "source-map": { "version": "0.7.3", "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.7.3.tgz", @@ -15326,6 +15691,15 @@ "integrity": "sha512-9NykojV5Uih4lgo5So5dtw+f0JgJX30KCNI8gwhz2J9A15wD0Ml6tjHKwf6fTSa6fAdVBdZeNOs9eJ71qCk8vA==", "dev": true }, + "sparse-bitfield": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/sparse-bitfield/-/sparse-bitfield-3.0.3.tgz", + "integrity": "sha512-kvzhi7vqKTfkh0PZU+2D2PIllw2ymqJKujUcyPMd9Y75Nv4nPbGJZXNhxsgdQab2BmlDct1YnfQCguEvHr7VsQ==", + "optional": true, + "requires": { + "memory-pager": "^1.0.2" + } + }, "sprintf-js": { "version": "1.0.3", "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz", diff --git a/package.json b/package.json index c75fb57..cedc094 100644 --- a/package.json +++ b/package.json @@ -25,6 +25,7 @@ "@nestjs/common": "^8.0.0", "@nestjs/config": "^2.0.1", "@nestjs/core": "^8.0.0", + "@nestjs/mongoose": "^9.1.0", "@nestjs/platform-express": "^8.0.0", "chai": "^4.3.6", "cheerio": "^1.0.0-rc.10", @@ -33,6 +34,7 @@ "dotenv": "^16.0.1", "fs": "^0.0.1-security", "js-yaml": "^4.1.0", + "mongoose": "^6.3.8", "nest-puppeteer": "^1.1.1", "puppeteer": "^14.1.0", "reflect-metadata": "^0.1.13", diff --git a/src/app.module.ts b/src/app.module.ts index 19c8308..027cc12 100644 --- a/src/app.module.ts +++ b/src/app.module.ts @@ -1,5 +1,7 @@ import { ClassSerializerInterceptor, Module } from '@nestjs/common'; +import { ConfigModule, ConfigService } from '@nestjs/config'; import { APP_INTERCEPTOR } from '@nestjs/core'; +import { MongooseModule } from '@nestjs/mongoose'; import { PuppeteerModule } from 'nest-puppeteer'; import { FiltersModule } from './core/error-handling/filters.module'; import { TransformResponseInterceptor } from './core/http/transform-response.interceptor'; @@ -13,6 +15,13 @@ import { NeighborhoodsModule } from './microservice/adapter/neighborhoods.module PuppeteerModule.forRoot({ isGlobal: true }), + MongooseModule.forRootAsync({ + imports: [ConfigModule], + inject: [ConfigService], + useFactory: async (config: ConfigService) => ({ + uri: config.get('database.mongodb.connection') + }) + }), NeighborhoodsModule ], controllers: [], diff --git a/src/microservice/adapter/controller/neighborhoods.controller.ts b/src/microservice/adapter/controller/neighborhoods.controller.ts index 7f52f7b..c90e583 100644 --- a/src/microservice/adapter/controller/neighborhoods.controller.ts +++ b/src/microservice/adapter/controller/neighborhoods.controller.ts @@ -20,4 +20,12 @@ export class NeighborhoodsController extends AbstractController { this.neighborhoodsService.getNeighborhoodsByCity(country, state, city) ); } + + @Get() + async getAll() { + return this.buildResponse( + HttpStatus.OK, + await this.neighborhoodsService.getAll() + ); + } } diff --git a/src/microservice/adapter/neighborhoods.module.ts b/src/microservice/adapter/neighborhoods.module.ts index 9875e43..4880a08 100644 --- a/src/microservice/adapter/neighborhoods.module.ts +++ b/src/microservice/adapter/neighborhoods.module.ts @@ -2,9 +2,15 @@ import { Module } from '@nestjs/common'; import { ConfigModule } from '@nestjs/config'; import { PuppeteerModule } from 'nest-puppeteer'; import { NeighborhoodsController } from './controller/neighborhoods.controller'; -import { GuiaMaisRepository } from './repository/neighborhoods/guia-mais.repository'; +import { GuiaMaisRepository } from './repository/neighborhoods/puppeteer/guia-mais.repository'; import { NeighborhoodsService } from './service/neighborhoods.service'; import configuration from '../../config/configuration'; +import { NeighborhoodsMongoose } from './repository/neighborhoods/neighborhoods-mongoose.repository'; +import { + Neighborhood, + NeighborhoodSchema +} from '../domain/schemas/neighborhood.schema'; +import { MongooseModule } from '@nestjs/mongoose'; @Module({ imports: [ @@ -12,7 +18,10 @@ import configuration from '../../config/configuration'; ConfigModule.forRoot({ isGlobal: true, load: [configuration] - }) + }), + MongooseModule.forFeature([ + { name: Neighborhood.name, schema: NeighborhoodSchema } + ]) ], controllers: [NeighborhoodsController], providers: [ @@ -20,6 +29,7 @@ import configuration from '../../config/configuration'; provide: 'GuiaMaisRepository', useClass: GuiaMaisRepository }, + NeighborhoodsMongoose, NeighborhoodsService ] }) diff --git a/src/microservice/adapter/repository/neighborhoods/neighborhoods-mongoose.repository.ts b/src/microservice/adapter/repository/neighborhoods/neighborhoods-mongoose.repository.ts new file mode 100644 index 0000000..6b0d3a9 --- /dev/null +++ b/src/microservice/adapter/repository/neighborhoods/neighborhoods-mongoose.repository.ts @@ -0,0 +1,19 @@ +import { Injectable } from '@nestjs/common'; +import { InjectModel } from '@nestjs/mongoose'; +import { Model } from 'mongoose'; +import { + Neighborhood, + NeighborhoodDocument +} from '../../../domain/schemas/neighborhood.schema'; + +@Injectable() +export class NeighborhoodsMongoose { + constructor( + @InjectModel(Neighborhood.name) + private neighborhoodsModel: Model + ) {} + + async findAll(): Promise { + return await this.neighborhoodsModel.find({}).exec(); + } +} diff --git a/src/microservice/adapter/repository/neighborhoods/guia-mais.repository.ts b/src/microservice/adapter/repository/neighborhoods/puppeteer/guia-mais.repository.ts similarity index 67% rename from src/microservice/adapter/repository/neighborhoods/guia-mais.repository.ts rename to src/microservice/adapter/repository/neighborhoods/puppeteer/guia-mais.repository.ts index 6e5fb58..66d3c73 100644 --- a/src/microservice/adapter/repository/neighborhoods/guia-mais.repository.ts +++ b/src/microservice/adapter/repository/neighborhoods/puppeteer/guia-mais.repository.ts @@ -2,11 +2,11 @@ import { Injectable } from '@nestjs/common'; import { ConfigService } from '@nestjs/config'; import { CheerioAPI } from 'cheerio'; import { InjectPage } from 'nest-puppeteer'; -import { NeighborhoodsByCity } from '../../../domain/model/neighborhoods-by-city.model'; -import { SearchNeighborhoods } from '../../../domain/model/search/search-neighborhoods.model'; -import { IPuppeteerNeighborhoodRepository } from '../../../domain/interface/puppeteer/repository/puppeteer-neighborhood-repository.interface'; -import { PuppeteerNeighborhoodRepository } from '../../../domain/repository/puppeteer/neighborhood/puppeteer-neighborhood.repository'; -import { Page } from '../../../domain/interface/puppeteer/page.interface'; +import { NeighborhoodsByCity } from '../../../../domain/model/neighborhoods-by-city.model'; +import { SearchNeighborhoods } from '../../../../domain/model/search/search-neighborhoods.model'; +import { IPuppeteerNeighborhoodRepository } from '../../../../domain/interface/puppeteer/repository/puppeteer-neighborhood-repository.interface'; +import { PuppeteerNeighborhoodRepository } from '../../../../domain/repository/puppeteer/neighborhood/puppeteer-neighborhood.repository'; +import { Page } from '../../../../domain/interface/puppeteer/page.interface'; @Injectable() export class GuiaMaisRepository diff --git a/src/microservice/adapter/service/neighborhoods.service.ts b/src/microservice/adapter/service/neighborhoods.service.ts index 04c365c..7c1fe2b 100644 --- a/src/microservice/adapter/service/neighborhoods.service.ts +++ b/src/microservice/adapter/service/neighborhoods.service.ts @@ -2,14 +2,16 @@ import { Inject, Injectable } from '@nestjs/common'; import { NeighborhoodsByCity } from '../../domain/model/neighborhoods-by-city.model'; import { SearchNeighborhoods } from '../../domain/model/search/search-neighborhoods.model'; import { INeighborhoodsService } from '../../domain/service/neighborhoods-service.interface'; +import { NeighborhoodsMongoose } from '../repository/neighborhoods/neighborhoods-mongoose.repository'; -import { GuiaMaisRepository } from '../repository/neighborhoods/guia-mais.repository'; +import { GuiaMaisRepository } from '../repository/neighborhoods/puppeteer/guia-mais.repository'; @Injectable() export class NeighborhoodsService implements INeighborhoodsService { constructor( @Inject('GuiaMaisRepository') - private readonly guiaMaisRepository: GuiaMaisRepository + private readonly guiaMaisRepository: GuiaMaisRepository, + private readonly mongoRepository: NeighborhoodsMongoose ) {} async getNeighborhoodsByCity( @@ -20,4 +22,8 @@ export class NeighborhoodsService implements INeighborhoodsService { const searchParams = new SearchNeighborhoods(country, state, city); return this.guiaMaisRepository.getNeighborhoodsByCity(searchParams); } + + async getAll() { + return this.mongoRepository.findAll(); + } } diff --git a/src/microservice/domain/schemas/neighborhood.schema.ts b/src/microservice/domain/schemas/neighborhood.schema.ts new file mode 100644 index 0000000..da2fbd6 --- /dev/null +++ b/src/microservice/domain/schemas/neighborhood.schema.ts @@ -0,0 +1,12 @@ +import { Prop, Schema, SchemaFactory } from '@nestjs/mongoose'; +import { Document } from 'mongoose'; + +export type NeighborhoodDocument = Neighborhood & Document; + +@Schema() +export class Neighborhood { + @Prop({ required: true }) + name: string; +} + +export const NeighborhoodSchema = SchemaFactory.createForClass(Neighborhood); diff --git a/test/unit/microservice/adapter/repository/neighborhoods/guia-mais.repository.spec.ts b/test/unit/microservice/adapter/repository/neighborhoods/puppeteer/guia-mais.repository.spec.ts similarity index 86% rename from test/unit/microservice/adapter/repository/neighborhoods/guia-mais.repository.spec.ts rename to test/unit/microservice/adapter/repository/neighborhoods/puppeteer/guia-mais.repository.spec.ts index 3dbebae..2c16ed4 100644 --- a/test/unit/microservice/adapter/repository/neighborhoods/guia-mais.repository.spec.ts +++ b/test/unit/microservice/adapter/repository/neighborhoods/puppeteer/guia-mais.repository.spec.ts @@ -2,11 +2,11 @@ import { Test, TestingModule } from '@nestjs/testing'; import { ConfigService } from '@nestjs/config'; import { expect } from 'chai'; import * as sinon from 'sinon'; -import { GuiaMaisRepository } from '../../../../../../src/microservice/adapter/repository/neighborhoods/guia-mais.repository'; +import { GuiaMaisRepository } from '../../../../../../../src/microservice/adapter/repository/neighborhoods/puppeteer/guia-mais.repository'; import { PuppeteerModule } from 'nest-puppeteer'; -import { SearchNeighborhoods } from '../../../../../../src/microservice/domain/model/search/search-neighborhoods.model'; +import { SearchNeighborhoods } from '../../../../../../../src/microservice/domain/model/search/search-neighborhoods.model'; import * as fs from 'fs'; -import { ExtensionsModule } from '../../../../../../src/microservice/adapter/helper/extensions/exensions.module'; +import { ExtensionsModule } from '../../../../../../../src/microservice/adapter/helper/extensions/exensions.module'; import * as cheerio from 'cheerio'; jest.useFakeTimers(); From a07a1ef81ca7895abadcbf7715dbdc85a78eeb07 Mon Sep 17 00:00:00 2001 From: Maick Speck Date: Mon, 13 Jun 2022 22:31:32 -0300 Subject: [PATCH 02/16] schema collection neighborhoods --- .../controller/neighborhoods.controller.ts | 14 +++++++++- .../adapter/neighborhoods.module.ts | 2 +- .../neighborhoods-mongoose.repository.ts | 27 ++++++++++++++++++- .../domain/schemas/neighborhood.schema.ts | 24 +++++++++++++++++ .../service/neighborhoods.service.ts | 14 ++++++---- .../neighborhoods.controller.spec.ts | 2 +- .../service/neighborhoods.service.spec.ts | 2 +- 7 files changed, 75 insertions(+), 10 deletions(-) rename src/microservice/{adapter => domain}/service/neighborhoods.service.ts (51%) rename test/unit/microservice/{adapter => domain}/service/neighborhoods.service.spec.ts (93%) diff --git a/src/microservice/adapter/controller/neighborhoods.controller.ts b/src/microservice/adapter/controller/neighborhoods.controller.ts index c90e583..8b5f431 100644 --- a/src/microservice/adapter/controller/neighborhoods.controller.ts +++ b/src/microservice/adapter/controller/neighborhoods.controller.ts @@ -1,7 +1,7 @@ import { Controller, Get, HttpStatus, Param } from '@nestjs/common'; import { NestResponse } from '../../../core/http/nest-response'; import { AbstractController } from '../../domain/controller/abstract-controller'; -import { NeighborhoodsService } from '../service/neighborhoods.service'; +import { NeighborhoodsService } from '../../domain/service/neighborhoods.service'; @Controller('neighborhoods') export class NeighborhoodsController extends AbstractController { @@ -28,4 +28,16 @@ export class NeighborhoodsController extends AbstractController { await this.neighborhoodsService.getAll() ); } + + @Get('/mongo/:country/:state/:city') + getMongoByCity( + @Param('country') country, + @Param('state') state, + @Param('city') city + ): NestResponse { + return this.buildResponse( + HttpStatus.OK, + this.neighborhoodsService.getMongoByCity(country, state, city) + ); + } } diff --git a/src/microservice/adapter/neighborhoods.module.ts b/src/microservice/adapter/neighborhoods.module.ts index 4880a08..e3c1bb5 100644 --- a/src/microservice/adapter/neighborhoods.module.ts +++ b/src/microservice/adapter/neighborhoods.module.ts @@ -3,7 +3,7 @@ import { ConfigModule } from '@nestjs/config'; import { PuppeteerModule } from 'nest-puppeteer'; import { NeighborhoodsController } from './controller/neighborhoods.controller'; import { GuiaMaisRepository } from './repository/neighborhoods/puppeteer/guia-mais.repository'; -import { NeighborhoodsService } from './service/neighborhoods.service'; +import { NeighborhoodsService } from '../domain/service/neighborhoods.service'; import configuration from '../../config/configuration'; import { NeighborhoodsMongoose } from './repository/neighborhoods/neighborhoods-mongoose.repository'; import { diff --git a/src/microservice/adapter/repository/neighborhoods/neighborhoods-mongoose.repository.ts b/src/microservice/adapter/repository/neighborhoods/neighborhoods-mongoose.repository.ts index 6b0d3a9..2764859 100644 --- a/src/microservice/adapter/repository/neighborhoods/neighborhoods-mongoose.repository.ts +++ b/src/microservice/adapter/repository/neighborhoods/neighborhoods-mongoose.repository.ts @@ -14,6 +14,31 @@ export class NeighborhoodsMongoose { ) {} async findAll(): Promise { - return await this.neighborhoodsModel.find({}).exec(); + return await this.neighborhoodsModel + .find() + .select({ _id: 0 }) + .lean() + .exec(); + } + + async findByCountryStateAndCity( + country: string, + state: string, + city: string + ): Promise { + console.log({ + country, + 'states.name': state, + 'states.cities.name': city + }); + return await this.neighborhoodsModel + .find({ + country, + 'states.name': state, + 'states.cities.name': city + }) + .select({ _id: 0 }) + .lean() + .exec(); } } diff --git a/src/microservice/domain/schemas/neighborhood.schema.ts b/src/microservice/domain/schemas/neighborhood.schema.ts index da2fbd6..96d8ad3 100644 --- a/src/microservice/domain/schemas/neighborhood.schema.ts +++ b/src/microservice/domain/schemas/neighborhood.schema.ts @@ -5,6 +5,30 @@ export type NeighborhoodDocument = Neighborhood & Document; @Schema() export class Neighborhood { + @Prop({ required: true }) + country: string; + + @Prop({ required: true }) + states: States[]; +} + +class States { + @Prop({ required: true }) + name: string; + + @Prop({ required: true }) + cities: Cities[]; +} + +class Cities { + @Prop({ required: true }) + name: string; + + @Prop({ required: true }) + cities: Neighborhoods[]; +} + +class Neighborhoods { @Prop({ required: true }) name: string; } diff --git a/src/microservice/adapter/service/neighborhoods.service.ts b/src/microservice/domain/service/neighborhoods.service.ts similarity index 51% rename from src/microservice/adapter/service/neighborhoods.service.ts rename to src/microservice/domain/service/neighborhoods.service.ts index 7c1fe2b..9da2c2b 100644 --- a/src/microservice/adapter/service/neighborhoods.service.ts +++ b/src/microservice/domain/service/neighborhoods.service.ts @@ -1,10 +1,10 @@ import { Inject, Injectable } from '@nestjs/common'; -import { NeighborhoodsByCity } from '../../domain/model/neighborhoods-by-city.model'; -import { SearchNeighborhoods } from '../../domain/model/search/search-neighborhoods.model'; -import { INeighborhoodsService } from '../../domain/service/neighborhoods-service.interface'; -import { NeighborhoodsMongoose } from '../repository/neighborhoods/neighborhoods-mongoose.repository'; +import { NeighborhoodsByCity } from '../model/neighborhoods-by-city.model'; +import { SearchNeighborhoods } from '../model/search/search-neighborhoods.model'; +import { INeighborhoodsService } from './neighborhoods-service.interface'; +import { NeighborhoodsMongoose } from '../../adapter/repository/neighborhoods/neighborhoods-mongoose.repository'; -import { GuiaMaisRepository } from '../repository/neighborhoods/puppeteer/guia-mais.repository'; +import { GuiaMaisRepository } from '../../adapter/repository/neighborhoods/puppeteer/guia-mais.repository'; @Injectable() export class NeighborhoodsService implements INeighborhoodsService { @@ -26,4 +26,8 @@ export class NeighborhoodsService implements INeighborhoodsService { async getAll() { return this.mongoRepository.findAll(); } + + async getMongoByCity(country: string, state: string, city: string) { + return this.mongoRepository.findByCountryStateAndCity(country, state, city); + } } diff --git a/test/unit/microservice/adapter/controller/neighborhoods.controller.spec.ts b/test/unit/microservice/adapter/controller/neighborhoods.controller.spec.ts index c7e3ccd..29da3e4 100644 --- a/test/unit/microservice/adapter/controller/neighborhoods.controller.spec.ts +++ b/test/unit/microservice/adapter/controller/neighborhoods.controller.spec.ts @@ -6,7 +6,7 @@ import { expect } from 'chai'; import * as sinon from 'sinon'; import { NeighborhoodsByCity } from '../../../../../src/microservice/domain/model/neighborhoods-by-city.model'; import { ExtensionsModule } from '../../../../../src/microservice/adapter/helper/extensions/exensions.module'; -import { NeighborhoodsService } from '../../../../../src/microservice/adapter/service/neighborhoods.service'; +import { NeighborhoodsService } from '../../../../../src/microservice/domain/service/neighborhoods.service'; describe('NeighborhoodsController', () => { let neighborhoodsController: NeighborhoodsController; diff --git a/test/unit/microservice/adapter/service/neighborhoods.service.spec.ts b/test/unit/microservice/domain/service/neighborhoods.service.spec.ts similarity index 93% rename from test/unit/microservice/adapter/service/neighborhoods.service.spec.ts rename to test/unit/microservice/domain/service/neighborhoods.service.spec.ts index 5b5afb0..6193d1c 100644 --- a/test/unit/microservice/adapter/service/neighborhoods.service.spec.ts +++ b/test/unit/microservice/domain/service/neighborhoods.service.spec.ts @@ -1,5 +1,5 @@ import { Test, TestingModule } from '@nestjs/testing'; -import { NeighborhoodsService } from '../../../../../src/microservice/adapter/service/neighborhoods.service'; +import { NeighborhoodsService } from '../../../../../src/microservice/domain/service/neighborhoods.service'; import { expect } from 'chai'; import * as sinon from 'sinon'; import { NeighborhoodsByCity } from '../../../../../src/microservice/domain/model/neighborhoods-by-city.model'; From 413715ca4a37c0c1de7d71386bba2c14740a1d4f Mon Sep 17 00:00:00 2001 From: Maick Speck Date: Thu, 16 Jun 2022 19:24:33 -0300 Subject: [PATCH 03/16] find in mongo get call --- .../controller/neighborhoods.controller.ts | 36 ++++++++------ .../builder/neighborhoods-mongo.builder.ts | 23 +++++++++ .../adapter/neighborhoods.module.ts | 4 +- .../neighborhoods-service.interface.ts | 2 +- .../domain/schemas/neighborhood.schema.ts | 2 +- .../domain/service/neighborhoods.service.ts | 33 ------------- .../get-neighborhoods-by-city.service.ts | 47 +++++++++++++++++++ .../neighborhoods.controller.spec.ts | 4 +- ...get-neighborhoods-by-city.service.spec.ts} | 14 +++--- 9 files changed, 104 insertions(+), 61 deletions(-) create mode 100644 src/microservice/adapter/helper/builder/neighborhoods-mongo.builder.ts rename src/microservice/domain/{ => interface}/service/neighborhoods-service.interface.ts (65%) delete mode 100644 src/microservice/domain/service/neighborhoods.service.ts create mode 100644 src/microservice/domain/service/neighborhoods/get-neighborhoods-by-city.service.ts rename test/unit/microservice/domain/service/{neighborhoods.service.spec.ts => neighborhoods/get-neighborhoods-by-city.service.spec.ts} (66%) diff --git a/src/microservice/adapter/controller/neighborhoods.controller.ts b/src/microservice/adapter/controller/neighborhoods.controller.ts index 8b5f431..b326d51 100644 --- a/src/microservice/adapter/controller/neighborhoods.controller.ts +++ b/src/microservice/adapter/controller/neighborhoods.controller.ts @@ -1,11 +1,13 @@ import { Controller, Get, HttpStatus, Param } from '@nestjs/common'; import { NestResponse } from '../../../core/http/nest-response'; import { AbstractController } from '../../domain/controller/abstract-controller'; -import { NeighborhoodsService } from '../../domain/service/neighborhoods.service'; +import { GetNeighborhoodsByCityService } from '../../domain/service/neighborhoods/get-neighborhoods-by-city.service'; @Controller('neighborhoods') export class NeighborhoodsController extends AbstractController { - constructor(private readonly neighborhoodsService: NeighborhoodsService) { + constructor( + private readonly getNeighborhoodsByCityService: GetNeighborhoodsByCityService + ) { super(); } @@ -17,7 +19,11 @@ export class NeighborhoodsController extends AbstractController { ): NestResponse { return this.buildResponse( HttpStatus.OK, - this.neighborhoodsService.getNeighborhoodsByCity(country, state, city) + this.getNeighborhoodsByCityService.getNeighborhoodsByCity( + country, + state, + city + ) ); } @@ -25,19 +31,19 @@ export class NeighborhoodsController extends AbstractController { async getAll() { return this.buildResponse( HttpStatus.OK, - await this.neighborhoodsService.getAll() + await this.getNeighborhoodsByCityService.getAll() ); } - @Get('/mongo/:country/:state/:city') - getMongoByCity( - @Param('country') country, - @Param('state') state, - @Param('city') city - ): NestResponse { - return this.buildResponse( - HttpStatus.OK, - this.neighborhoodsService.getMongoByCity(country, state, city) - ); - } + // @Get('/mongo/:country/:state/:city') + // getMongoByCity( + // @Param('country') country, + // @Param('state') state, + // @Param('city') city + // ): NestResponse { + // return this.buildResponse( + // HttpStatus.OK, + // this.getNeighborhoodsByCityService.findInDatabase(country, state, city) + // ); + // } } diff --git a/src/microservice/adapter/helper/builder/neighborhoods-mongo.builder.ts b/src/microservice/adapter/helper/builder/neighborhoods-mongo.builder.ts new file mode 100644 index 0000000..599d79e --- /dev/null +++ b/src/microservice/adapter/helper/builder/neighborhoods-mongo.builder.ts @@ -0,0 +1,23 @@ +import { NeighborhoodsByCity } from '../../../domain/model/neighborhoods-by-city.model'; +import { Neighborhood } from '../../../domain/schemas/neighborhood.schema'; + +export class NeighborhoodsMongoBuilder { + constructor(private mongoResponse: Neighborhood[]) {} + + build(): NeighborhoodsByCity[] { + const arr = []; + this.mongoResponse.forEach((country) => { + country.states.forEach((state) => { + state.cities.forEach((city) => { + city.neighborhoods.forEach((item) => { + const obj = new NeighborhoodsByCity(); + obj.city = `${city.name.capitalize()} - ${state.name.toUpperCase()}`; + obj.name = item.name; + arr.push(obj); + }); + }); + }); + }); + return arr; + } +} diff --git a/src/microservice/adapter/neighborhoods.module.ts b/src/microservice/adapter/neighborhoods.module.ts index e3c1bb5..8316446 100644 --- a/src/microservice/adapter/neighborhoods.module.ts +++ b/src/microservice/adapter/neighborhoods.module.ts @@ -3,7 +3,7 @@ import { ConfigModule } from '@nestjs/config'; import { PuppeteerModule } from 'nest-puppeteer'; import { NeighborhoodsController } from './controller/neighborhoods.controller'; import { GuiaMaisRepository } from './repository/neighborhoods/puppeteer/guia-mais.repository'; -import { NeighborhoodsService } from '../domain/service/neighborhoods.service'; +import { GetNeighborhoodsByCityService } from '../domain/service/neighborhoods/get-neighborhoods-by-city.service'; import configuration from '../../config/configuration'; import { NeighborhoodsMongoose } from './repository/neighborhoods/neighborhoods-mongoose.repository'; import { @@ -30,7 +30,7 @@ import { MongooseModule } from '@nestjs/mongoose'; useClass: GuiaMaisRepository }, NeighborhoodsMongoose, - NeighborhoodsService + GetNeighborhoodsByCityService ] }) export class NeighborhoodsModule {} diff --git a/src/microservice/domain/service/neighborhoods-service.interface.ts b/src/microservice/domain/interface/service/neighborhoods-service.interface.ts similarity index 65% rename from src/microservice/domain/service/neighborhoods-service.interface.ts rename to src/microservice/domain/interface/service/neighborhoods-service.interface.ts index 23deec8..d471334 100644 --- a/src/microservice/domain/service/neighborhoods-service.interface.ts +++ b/src/microservice/domain/interface/service/neighborhoods-service.interface.ts @@ -1,4 +1,4 @@ -import { NeighborhoodsByCity } from '../model/neighborhoods-by-city.model'; +import { NeighborhoodsByCity } from '../../model/neighborhoods-by-city.model'; export interface INeighborhoodsService { getNeighborhoodsByCity( diff --git a/src/microservice/domain/schemas/neighborhood.schema.ts b/src/microservice/domain/schemas/neighborhood.schema.ts index 96d8ad3..a75376c 100644 --- a/src/microservice/domain/schemas/neighborhood.schema.ts +++ b/src/microservice/domain/schemas/neighborhood.schema.ts @@ -25,7 +25,7 @@ class Cities { name: string; @Prop({ required: true }) - cities: Neighborhoods[]; + neighborhoods: Neighborhoods[]; } class Neighborhoods { diff --git a/src/microservice/domain/service/neighborhoods.service.ts b/src/microservice/domain/service/neighborhoods.service.ts deleted file mode 100644 index 9da2c2b..0000000 --- a/src/microservice/domain/service/neighborhoods.service.ts +++ /dev/null @@ -1,33 +0,0 @@ -import { Inject, Injectable } from '@nestjs/common'; -import { NeighborhoodsByCity } from '../model/neighborhoods-by-city.model'; -import { SearchNeighborhoods } from '../model/search/search-neighborhoods.model'; -import { INeighborhoodsService } from './neighborhoods-service.interface'; -import { NeighborhoodsMongoose } from '../../adapter/repository/neighborhoods/neighborhoods-mongoose.repository'; - -import { GuiaMaisRepository } from '../../adapter/repository/neighborhoods/puppeteer/guia-mais.repository'; - -@Injectable() -export class NeighborhoodsService implements INeighborhoodsService { - constructor( - @Inject('GuiaMaisRepository') - private readonly guiaMaisRepository: GuiaMaisRepository, - private readonly mongoRepository: NeighborhoodsMongoose - ) {} - - async getNeighborhoodsByCity( - country: string, - state: string, - city: string - ): Promise { - const searchParams = new SearchNeighborhoods(country, state, city); - return this.guiaMaisRepository.getNeighborhoodsByCity(searchParams); - } - - async getAll() { - return this.mongoRepository.findAll(); - } - - async getMongoByCity(country: string, state: string, city: string) { - return this.mongoRepository.findByCountryStateAndCity(country, state, city); - } -} diff --git a/src/microservice/domain/service/neighborhoods/get-neighborhoods-by-city.service.ts b/src/microservice/domain/service/neighborhoods/get-neighborhoods-by-city.service.ts new file mode 100644 index 0000000..1eecc7e --- /dev/null +++ b/src/microservice/domain/service/neighborhoods/get-neighborhoods-by-city.service.ts @@ -0,0 +1,47 @@ +import { Inject, Injectable } from '@nestjs/common'; +import { NeighborhoodsByCity } from '../../model/neighborhoods-by-city.model'; +import { SearchNeighborhoods } from '../../model/search/search-neighborhoods.model'; +import { INeighborhoodsService } from '../../interface/service/neighborhoods-service.interface'; +import { NeighborhoodsMongoose } from '../../../adapter/repository/neighborhoods/neighborhoods-mongoose.repository'; +import { GuiaMaisRepository } from '../../../adapter/repository/neighborhoods/puppeteer/guia-mais.repository'; +import { NeighborhoodsMongoBuilder } from 'src/microservice/adapter/helper/builder/neighborhoods-mongo.builder'; + +@Injectable() +export class GetNeighborhoodsByCityService implements INeighborhoodsService { + constructor( + @Inject('GuiaMaisRepository') + private readonly guiaMaisRepository: GuiaMaisRepository, + private readonly mongoRepository: NeighborhoodsMongoose + ) {} + + async getNeighborhoodsByCity( + country: string, + state: string, + city: string + ): Promise { + const searchParams = new SearchNeighborhoods(country, state, city); + + const resMongo = await this.findInDatabase(searchParams); + + if (!resMongo.length) + return await this.guiaMaisRepository.getNeighborhoodsByCity(searchParams); + + return resMongo; + } + + async getAll() { + return this.mongoRepository.findAll(); + } + + async findInDatabase( + searchParams: SearchNeighborhoods + ): Promise { + const res = await this.mongoRepository.findByCountryStateAndCity( + searchParams.country, + searchParams.state, + searchParams.city + ); + const builder = new NeighborhoodsMongoBuilder(res); + return builder.build(); + } +} diff --git a/test/unit/microservice/adapter/controller/neighborhoods.controller.spec.ts b/test/unit/microservice/adapter/controller/neighborhoods.controller.spec.ts index 29da3e4..6c6ebfd 100644 --- a/test/unit/microservice/adapter/controller/neighborhoods.controller.spec.ts +++ b/test/unit/microservice/adapter/controller/neighborhoods.controller.spec.ts @@ -6,7 +6,7 @@ import { expect } from 'chai'; import * as sinon from 'sinon'; import { NeighborhoodsByCity } from '../../../../../src/microservice/domain/model/neighborhoods-by-city.model'; import { ExtensionsModule } from '../../../../../src/microservice/adapter/helper/extensions/exensions.module'; -import { NeighborhoodsService } from '../../../../../src/microservice/domain/service/neighborhoods.service'; +import { GetNeighborhoodsByCityService } from '../../../../../src/microservice/domain/service/neighborhoods/get-neighborhoods-by-city.service'; describe('NeighborhoodsController', () => { let neighborhoodsController: NeighborhoodsController; @@ -40,7 +40,7 @@ describe('NeighborhoodsController', () => { controllers: [NeighborhoodsController], providers: [ { - provide: NeighborhoodsService, + provide: GetNeighborhoodsByCityService, useFactory: () => mockNeighborhoodsService } ] diff --git a/test/unit/microservice/domain/service/neighborhoods.service.spec.ts b/test/unit/microservice/domain/service/neighborhoods/get-neighborhoods-by-city.service.spec.ts similarity index 66% rename from test/unit/microservice/domain/service/neighborhoods.service.spec.ts rename to test/unit/microservice/domain/service/neighborhoods/get-neighborhoods-by-city.service.spec.ts index 6193d1c..1b8a537 100644 --- a/test/unit/microservice/domain/service/neighborhoods.service.spec.ts +++ b/test/unit/microservice/domain/service/neighborhoods/get-neighborhoods-by-city.service.spec.ts @@ -1,11 +1,11 @@ import { Test, TestingModule } from '@nestjs/testing'; -import { NeighborhoodsService } from '../../../../../src/microservice/domain/service/neighborhoods.service'; +import { GetNeighborhoodsByCityService } from '../../../../../../src/microservice/domain/service/neighborhoods/get-neighborhoods-by-city.service'; import { expect } from 'chai'; import * as sinon from 'sinon'; -import { NeighborhoodsByCity } from '../../../../../src/microservice/domain/model/neighborhoods-by-city.model'; +import { NeighborhoodsByCity } from '../../../../../../src/microservice/domain/model/neighborhoods-by-city.model'; -describe('NeighborhoodsService', () => { - let sut: NeighborhoodsService; +describe('GetNeighborhoodsByCityService', () => { + let sut: GetNeighborhoodsByCityService; const mockGuiaMaisRepository = { getNeighborhoodsByCity: () => { @@ -33,14 +33,14 @@ describe('NeighborhoodsService', () => { provide: 'GuiaMaisRepository', useValue: mockGuiaMaisRepository }, - NeighborhoodsService + GetNeighborhoodsByCityService ] }).compile(); - sut = app.get(NeighborhoodsService); + sut = app.get(GetNeighborhoodsByCityService); }); - describe('NeighborhoodsService', () => { + describe('GetNeighborhoodsByCityService', () => { it('should call getNeighborhoodsByCity and return an array', async () => { const guiaMaisStub = sinon .stub(mockGuiaMaisRepository, 'getNeighborhoodsByCity') From e27222b2ece9351ceef6fba0e52a88452a5ad1c3 Mon Sep 17 00:00:00 2001 From: Maick Speck Date: Fri, 17 Jun 2022 09:32:35 -0300 Subject: [PATCH 04/16] save document mongodb --- .../controller/neighborhoods.controller.ts | 12 ------- .../neighborhoods-puppeteer.builder.ts | 34 +++++++++++++++++++ .../adapter/helper/mongodb.helper.ts | 14 ++++++++ .../adapter/neighborhoods.module.ts | 4 ++- .../neighborhoods-mongoose.repository.ts | 17 +++++----- .../neighborhoods-service.interface.ts | 9 ----- .../domain/repository/mongoose.repository.ts | 10 ++++++ .../domain/schemas/neighborhood.schema.ts | 11 +++--- .../get-neighborhoods-by-city.service.ts | 22 ++++++++---- .../save-neighborhoods-by-city.service.ts | 20 +++++++++++ 10 files changed, 111 insertions(+), 42 deletions(-) create mode 100644 src/microservice/adapter/helper/builder/neighborhoods-puppeteer.builder.ts create mode 100644 src/microservice/adapter/helper/mongodb.helper.ts delete mode 100644 src/microservice/domain/interface/service/neighborhoods-service.interface.ts create mode 100644 src/microservice/domain/repository/mongoose.repository.ts create mode 100644 src/microservice/domain/service/neighborhoods/save-neighborhoods-by-city.service.ts diff --git a/src/microservice/adapter/controller/neighborhoods.controller.ts b/src/microservice/adapter/controller/neighborhoods.controller.ts index b326d51..e0b3146 100644 --- a/src/microservice/adapter/controller/neighborhoods.controller.ts +++ b/src/microservice/adapter/controller/neighborhoods.controller.ts @@ -34,16 +34,4 @@ export class NeighborhoodsController extends AbstractController { await this.getNeighborhoodsByCityService.getAll() ); } - - // @Get('/mongo/:country/:state/:city') - // getMongoByCity( - // @Param('country') country, - // @Param('state') state, - // @Param('city') city - // ): NestResponse { - // return this.buildResponse( - // HttpStatus.OK, - // this.getNeighborhoodsByCityService.findInDatabase(country, state, city) - // ); - // } } diff --git a/src/microservice/adapter/helper/builder/neighborhoods-puppeteer.builder.ts b/src/microservice/adapter/helper/builder/neighborhoods-puppeteer.builder.ts new file mode 100644 index 0000000..39be114 --- /dev/null +++ b/src/microservice/adapter/helper/builder/neighborhoods-puppeteer.builder.ts @@ -0,0 +1,34 @@ +import { SearchNeighborhoods } from 'src/microservice/domain/model/search/search-neighborhoods.model'; +import { NeighborhoodsByCity } from '../../../domain/model/neighborhoods-by-city.model'; +import { + CitiesNeighborhood, + Neighborhood, + Neighborhoods, + StatesNeighborhood +} from '../../../domain/schemas/neighborhood.schema'; +import { MongoDBHelper } from '../mongodb.helper'; + +export class NeighborhoodsPuppeteerBuilder { + constructor(private puppeteerResponse: NeighborhoodsByCity[]) {} + + build(searchParams: SearchNeighborhoods): Neighborhood { + const obj = new Neighborhood(); + obj.country = searchParams.country; + const state = new StatesNeighborhood(); + state.name = searchParams.state; + const city = new CitiesNeighborhood(); + city.name = searchParams.city; + city.neighborhoods = []; + + this.puppeteerResponse.forEach((item) => { + const neighborhood = new Neighborhoods(); + neighborhood.name = item.name; + neighborhood._id = MongoDBHelper.generateObjectID(); + city.neighborhoods.push(neighborhood); + }); + + state.cities = [city]; + obj.states = [state]; + return obj; + } +} diff --git a/src/microservice/adapter/helper/mongodb.helper.ts b/src/microservice/adapter/helper/mongodb.helper.ts new file mode 100644 index 0000000..82e0e8f --- /dev/null +++ b/src/microservice/adapter/helper/mongodb.helper.ts @@ -0,0 +1,14 @@ +export class MongoDBHelper { + static generateObjectID(length = 16): string { + const timestamp = ((new Date().getTime() / 1000) | 0).toString(length); + return ( + timestamp + + 'x' + .repeat(length) + .replace(/[x]/g, function () { + return ((Math.random() * length) | 0).toString(length); + }) + .toLowerCase() + ); + } +} diff --git a/src/microservice/adapter/neighborhoods.module.ts b/src/microservice/adapter/neighborhoods.module.ts index 8316446..9ad0f6e 100644 --- a/src/microservice/adapter/neighborhoods.module.ts +++ b/src/microservice/adapter/neighborhoods.module.ts @@ -11,6 +11,7 @@ import { NeighborhoodSchema } from '../domain/schemas/neighborhood.schema'; import { MongooseModule } from '@nestjs/mongoose'; +import { SaveNeighborhoodsByCityService } from '../domain/service/neighborhoods/save-neighborhoods-by-city.service'; @Module({ imports: [ @@ -30,7 +31,8 @@ import { MongooseModule } from '@nestjs/mongoose'; useClass: GuiaMaisRepository }, NeighborhoodsMongoose, - GetNeighborhoodsByCityService + GetNeighborhoodsByCityService, + SaveNeighborhoodsByCityService ] }) export class NeighborhoodsModule {} diff --git a/src/microservice/adapter/repository/neighborhoods/neighborhoods-mongoose.repository.ts b/src/microservice/adapter/repository/neighborhoods/neighborhoods-mongoose.repository.ts index 2764859..704b42f 100644 --- a/src/microservice/adapter/repository/neighborhoods/neighborhoods-mongoose.repository.ts +++ b/src/microservice/adapter/repository/neighborhoods/neighborhoods-mongoose.repository.ts @@ -1,24 +1,23 @@ import { Injectable } from '@nestjs/common'; import { InjectModel } from '@nestjs/mongoose'; import { Model } from 'mongoose'; +import { MongooseRepository } from '../../../domain/repository/mongoose.repository'; import { Neighborhood, NeighborhoodDocument } from '../../../domain/schemas/neighborhood.schema'; @Injectable() -export class NeighborhoodsMongoose { +export class NeighborhoodsMongoose extends MongooseRepository { constructor( @InjectModel(Neighborhood.name) - private neighborhoodsModel: Model - ) {} + protected model: Model + ) { + super(model); + } async findAll(): Promise { - return await this.neighborhoodsModel - .find() - .select({ _id: 0 }) - .lean() - .exec(); + return await this.model.find().select({ _id: 0 }).lean().exec(); } async findByCountryStateAndCity( @@ -31,7 +30,7 @@ export class NeighborhoodsMongoose { 'states.name': state, 'states.cities.name': city }); - return await this.neighborhoodsModel + return await this.model .find({ country, 'states.name': state, diff --git a/src/microservice/domain/interface/service/neighborhoods-service.interface.ts b/src/microservice/domain/interface/service/neighborhoods-service.interface.ts deleted file mode 100644 index d471334..0000000 --- a/src/microservice/domain/interface/service/neighborhoods-service.interface.ts +++ /dev/null @@ -1,9 +0,0 @@ -import { NeighborhoodsByCity } from '../../model/neighborhoods-by-city.model'; - -export interface INeighborhoodsService { - getNeighborhoodsByCity( - country: string, - state: string, - city: string - ): Promise; -} diff --git a/src/microservice/domain/repository/mongoose.repository.ts b/src/microservice/domain/repository/mongoose.repository.ts new file mode 100644 index 0000000..547e77f --- /dev/null +++ b/src/microservice/domain/repository/mongoose.repository.ts @@ -0,0 +1,10 @@ +import { Model } from 'mongoose'; +import { NeighborhoodDocument } from '../schemas/neighborhood.schema'; + +export abstract class MongooseRepository { + constructor(protected model: Model) {} + + async insert(document: Collection): Promise { + this.model.create(document); + } +} diff --git a/src/microservice/domain/schemas/neighborhood.schema.ts b/src/microservice/domain/schemas/neighborhood.schema.ts index a75376c..77c8072 100644 --- a/src/microservice/domain/schemas/neighborhood.schema.ts +++ b/src/microservice/domain/schemas/neighborhood.schema.ts @@ -9,18 +9,18 @@ export class Neighborhood { country: string; @Prop({ required: true }) - states: States[]; + states: StatesNeighborhood[]; } -class States { +export class StatesNeighborhood { @Prop({ required: true }) name: string; @Prop({ required: true }) - cities: Cities[]; + cities: CitiesNeighborhood[]; } -class Cities { +export class CitiesNeighborhood { @Prop({ required: true }) name: string; @@ -28,9 +28,10 @@ class Cities { neighborhoods: Neighborhoods[]; } -class Neighborhoods { +export class Neighborhoods { @Prop({ required: true }) name: string; + _id: string; } export const NeighborhoodSchema = SchemaFactory.createForClass(Neighborhood); diff --git a/src/microservice/domain/service/neighborhoods/get-neighborhoods-by-city.service.ts b/src/microservice/domain/service/neighborhoods/get-neighborhoods-by-city.service.ts index 1eecc7e..e08a20d 100644 --- a/src/microservice/domain/service/neighborhoods/get-neighborhoods-by-city.service.ts +++ b/src/microservice/domain/service/neighborhoods/get-neighborhoods-by-city.service.ts @@ -1,16 +1,17 @@ import { Inject, Injectable } from '@nestjs/common'; import { NeighborhoodsByCity } from '../../model/neighborhoods-by-city.model'; import { SearchNeighborhoods } from '../../model/search/search-neighborhoods.model'; -import { INeighborhoodsService } from '../../interface/service/neighborhoods-service.interface'; import { NeighborhoodsMongoose } from '../../../adapter/repository/neighborhoods/neighborhoods-mongoose.repository'; import { GuiaMaisRepository } from '../../../adapter/repository/neighborhoods/puppeteer/guia-mais.repository'; import { NeighborhoodsMongoBuilder } from 'src/microservice/adapter/helper/builder/neighborhoods-mongo.builder'; +import { SaveNeighborhoodsByCityService } from './save-neighborhoods-by-city.service'; @Injectable() -export class GetNeighborhoodsByCityService implements INeighborhoodsService { +export class GetNeighborhoodsByCityService { constructor( @Inject('GuiaMaisRepository') private readonly guiaMaisRepository: GuiaMaisRepository, + private readonly saveNeighborhoodsService: SaveNeighborhoodsByCityService, private readonly mongoRepository: NeighborhoodsMongoose ) {} @@ -23,8 +24,18 @@ export class GetNeighborhoodsByCityService implements INeighborhoodsService { const resMongo = await this.findInDatabase(searchParams); - if (!resMongo.length) - return await this.guiaMaisRepository.getNeighborhoodsByCity(searchParams); + if (!resMongo.length) { + const resPuppeteer = await this.guiaMaisRepository.getNeighborhoodsByCity( + searchParams + ); + + await this.saveNeighborhoodsService.saveNeighborhoodsByCity( + resPuppeteer, + searchParams + ); + + return resPuppeteer; + } return resMongo; } @@ -41,7 +52,6 @@ export class GetNeighborhoodsByCityService implements INeighborhoodsService { searchParams.state, searchParams.city ); - const builder = new NeighborhoodsMongoBuilder(res); - return builder.build(); + return new NeighborhoodsMongoBuilder(res).build(); } } diff --git a/src/microservice/domain/service/neighborhoods/save-neighborhoods-by-city.service.ts b/src/microservice/domain/service/neighborhoods/save-neighborhoods-by-city.service.ts new file mode 100644 index 0000000..70562e0 --- /dev/null +++ b/src/microservice/domain/service/neighborhoods/save-neighborhoods-by-city.service.ts @@ -0,0 +1,20 @@ +import { Injectable } from '@nestjs/common'; +import { NeighborhoodsByCity } from '../../model/neighborhoods-by-city.model'; +import { NeighborhoodsMongoose } from '../../../adapter/repository/neighborhoods/neighborhoods-mongoose.repository'; +import { NeighborhoodsPuppeteerBuilder } from '../../../adapter/helper/builder/neighborhoods-puppeteer.builder'; +import { SearchNeighborhoods } from '../../model/search/search-neighborhoods.model'; + +@Injectable() +export class SaveNeighborhoodsByCityService { + constructor(private readonly mongoRepository: NeighborhoodsMongoose) {} + + async saveNeighborhoodsByCity( + neighborhoodsPuppeteer: NeighborhoodsByCity[], + searchParams: SearchNeighborhoods + ): Promise { + const obj = new NeighborhoodsPuppeteerBuilder(neighborhoodsPuppeteer).build( + searchParams + ); + await this.mongoRepository.insert(obj); + } +} From d8b950149fc5969340be6ef0e07d21a954c93f89 Mon Sep 17 00:00:00 2001 From: Maick Speck Date: Fri, 17 Jun 2022 10:12:08 -0300 Subject: [PATCH 05/16] restructure colleciton --- .../builder/neighborhoods-mongo.builder.ts | 16 +++------- .../neighborhoods-puppeteer.builder.ts | 32 ++++++------------- .../neighborhoods-mongoose.repository.ts | 24 +++----------- .../search/search-neighborhoods.model.ts | 6 ++++ .../domain/schemas/neighborhood.schema.ts | 20 ++---------- .../get-neighborhoods-by-city.service.ts | 25 ++++----------- .../neighborhoods/neighborhoods.service.ts | 19 +++++++++++ .../save-neighborhoods-by-city.service.ts | 31 ++++++++++++++---- 8 files changed, 78 insertions(+), 95 deletions(-) create mode 100644 src/microservice/domain/service/neighborhoods/neighborhoods.service.ts diff --git a/src/microservice/adapter/helper/builder/neighborhoods-mongo.builder.ts b/src/microservice/adapter/helper/builder/neighborhoods-mongo.builder.ts index 599d79e..bfa73c0 100644 --- a/src/microservice/adapter/helper/builder/neighborhoods-mongo.builder.ts +++ b/src/microservice/adapter/helper/builder/neighborhoods-mongo.builder.ts @@ -6,17 +6,11 @@ export class NeighborhoodsMongoBuilder { build(): NeighborhoodsByCity[] { const arr = []; - this.mongoResponse.forEach((country) => { - country.states.forEach((state) => { - state.cities.forEach((city) => { - city.neighborhoods.forEach((item) => { - const obj = new NeighborhoodsByCity(); - obj.city = `${city.name.capitalize()} - ${state.name.toUpperCase()}`; - obj.name = item.name; - arr.push(obj); - }); - }); - }); + this.mongoResponse.forEach((document) => { + const obj = new NeighborhoodsByCity(); + obj.city = `${document.city.capitalize()} - ${document.state.toUpperCase()}`; + obj.name = document.name; + arr.push(obj); }); return arr; } diff --git a/src/microservice/adapter/helper/builder/neighborhoods-puppeteer.builder.ts b/src/microservice/adapter/helper/builder/neighborhoods-puppeteer.builder.ts index 39be114..abddbef 100644 --- a/src/microservice/adapter/helper/builder/neighborhoods-puppeteer.builder.ts +++ b/src/microservice/adapter/helper/builder/neighborhoods-puppeteer.builder.ts @@ -1,34 +1,22 @@ import { SearchNeighborhoods } from 'src/microservice/domain/model/search/search-neighborhoods.model'; import { NeighborhoodsByCity } from '../../../domain/model/neighborhoods-by-city.model'; -import { - CitiesNeighborhood, - Neighborhood, - Neighborhoods, - StatesNeighborhood -} from '../../../domain/schemas/neighborhood.schema'; -import { MongoDBHelper } from '../mongodb.helper'; +import { Neighborhood } from '../../../domain/schemas/neighborhood.schema'; export class NeighborhoodsPuppeteerBuilder { constructor(private puppeteerResponse: NeighborhoodsByCity[]) {} - build(searchParams: SearchNeighborhoods): Neighborhood { - const obj = new Neighborhood(); - obj.country = searchParams.country; - const state = new StatesNeighborhood(); - state.name = searchParams.state; - const city = new CitiesNeighborhood(); - city.name = searchParams.city; - city.neighborhoods = []; + build(searchParams: SearchNeighborhoods): Neighborhood[] { + const arr = []; this.puppeteerResponse.forEach((item) => { - const neighborhood = new Neighborhoods(); - neighborhood.name = item.name; - neighborhood._id = MongoDBHelper.generateObjectID(); - city.neighborhoods.push(neighborhood); + const obj = new Neighborhood(); + obj.country = searchParams.country; + obj.state = searchParams.state; + obj.city = searchParams.city; + obj.name = item.name; + arr.push(obj); }); - state.cities = [city]; - obj.states = [state]; - return obj; + return arr; } } diff --git a/src/microservice/adapter/repository/neighborhoods/neighborhoods-mongoose.repository.ts b/src/microservice/adapter/repository/neighborhoods/neighborhoods-mongoose.repository.ts index 704b42f..c4197a8 100644 --- a/src/microservice/adapter/repository/neighborhoods/neighborhoods-mongoose.repository.ts +++ b/src/microservice/adapter/repository/neighborhoods/neighborhoods-mongoose.repository.ts @@ -1,6 +1,7 @@ import { Injectable } from '@nestjs/common'; import { InjectModel } from '@nestjs/mongoose'; import { Model } from 'mongoose'; +import { SearchNeighborhoods } from 'src/microservice/domain/model/search/search-neighborhoods.model'; import { MongooseRepository } from '../../../domain/repository/mongoose.repository'; import { Neighborhood, @@ -11,7 +12,7 @@ import { export class NeighborhoodsMongoose extends MongooseRepository { constructor( @InjectModel(Neighborhood.name) - protected model: Model + model: Model ) { super(model); } @@ -20,24 +21,9 @@ export class NeighborhoodsMongoose extends MongooseRepository { return await this.model.find().select({ _id: 0 }).lean().exec(); } - async findByCountryStateAndCity( - country: string, - state: string, - city: string + async findBySearchParams( + searchParams: SearchNeighborhoods ): Promise { - console.log({ - country, - 'states.name': state, - 'states.cities.name': city - }); - return await this.model - .find({ - country, - 'states.name': state, - 'states.cities.name': city - }) - .select({ _id: 0 }) - .lean() - .exec(); + return await this.model.find(searchParams).select({ _id: 0 }).lean().exec(); } } diff --git a/src/microservice/domain/model/search/search-neighborhoods.model.ts b/src/microservice/domain/model/search/search-neighborhoods.model.ts index 70a0222..67df7d6 100644 --- a/src/microservice/domain/model/search/search-neighborhoods.model.ts +++ b/src/microservice/domain/model/search/search-neighborhoods.model.ts @@ -1,7 +1,13 @@ export class SearchNeighborhoods { + public name: string; + constructor( public country: string, public state: string, public city: string ) {} + + setName(name: string) { + this.name = name; + } } diff --git a/src/microservice/domain/schemas/neighborhood.schema.ts b/src/microservice/domain/schemas/neighborhood.schema.ts index 77c8072..66197ed 100644 --- a/src/microservice/domain/schemas/neighborhood.schema.ts +++ b/src/microservice/domain/schemas/neighborhood.schema.ts @@ -9,29 +9,13 @@ export class Neighborhood { country: string; @Prop({ required: true }) - states: StatesNeighborhood[]; -} - -export class StatesNeighborhood { - @Prop({ required: true }) - name: string; + state: string; @Prop({ required: true }) - cities: CitiesNeighborhood[]; -} - -export class CitiesNeighborhood { - @Prop({ required: true }) - name: string; - - @Prop({ required: true }) - neighborhoods: Neighborhoods[]; -} + city: string; -export class Neighborhoods { @Prop({ required: true }) name: string; - _id: string; } export const NeighborhoodSchema = SchemaFactory.createForClass(Neighborhood); diff --git a/src/microservice/domain/service/neighborhoods/get-neighborhoods-by-city.service.ts b/src/microservice/domain/service/neighborhoods/get-neighborhoods-by-city.service.ts index e08a20d..08839c9 100644 --- a/src/microservice/domain/service/neighborhoods/get-neighborhoods-by-city.service.ts +++ b/src/microservice/domain/service/neighborhoods/get-neighborhoods-by-city.service.ts @@ -3,17 +3,19 @@ import { NeighborhoodsByCity } from '../../model/neighborhoods-by-city.model'; import { SearchNeighborhoods } from '../../model/search/search-neighborhoods.model'; import { NeighborhoodsMongoose } from '../../../adapter/repository/neighborhoods/neighborhoods-mongoose.repository'; import { GuiaMaisRepository } from '../../../adapter/repository/neighborhoods/puppeteer/guia-mais.repository'; -import { NeighborhoodsMongoBuilder } from 'src/microservice/adapter/helper/builder/neighborhoods-mongo.builder'; import { SaveNeighborhoodsByCityService } from './save-neighborhoods-by-city.service'; +import { NeighborhoodsService } from './neighborhoods.service'; @Injectable() -export class GetNeighborhoodsByCityService { +export class GetNeighborhoodsByCityService extends NeighborhoodsService { constructor( @Inject('GuiaMaisRepository') private readonly guiaMaisRepository: GuiaMaisRepository, private readonly saveNeighborhoodsService: SaveNeighborhoodsByCityService, - private readonly mongoRepository: NeighborhoodsMongoose - ) {} + mongoRepository: NeighborhoodsMongoose + ) { + super(mongoRepository); + } async getNeighborhoodsByCity( country: string, @@ -39,19 +41,4 @@ export class GetNeighborhoodsByCityService { return resMongo; } - - async getAll() { - return this.mongoRepository.findAll(); - } - - async findInDatabase( - searchParams: SearchNeighborhoods - ): Promise { - const res = await this.mongoRepository.findByCountryStateAndCity( - searchParams.country, - searchParams.state, - searchParams.city - ); - return new NeighborhoodsMongoBuilder(res).build(); - } } diff --git a/src/microservice/domain/service/neighborhoods/neighborhoods.service.ts b/src/microservice/domain/service/neighborhoods/neighborhoods.service.ts new file mode 100644 index 0000000..480eff3 --- /dev/null +++ b/src/microservice/domain/service/neighborhoods/neighborhoods.service.ts @@ -0,0 +1,19 @@ +import { NeighborhoodsMongoBuilder } from 'src/microservice/adapter/helper/builder/neighborhoods-mongo.builder'; +import { NeighborhoodsMongoose } from '../../../adapter/repository/neighborhoods/neighborhoods-mongoose.repository'; +import { NeighborhoodsByCity } from '../../model/neighborhoods-by-city.model'; +import { SearchNeighborhoods } from '../../model/search/search-neighborhoods.model'; + +export abstract class NeighborhoodsService { + constructor(protected readonly mongoRepository: NeighborhoodsMongoose) {} + + async getAll() { + return this.mongoRepository.findAll(); + } + + async findInDatabase( + searchParams: SearchNeighborhoods + ): Promise { + const res = await this.mongoRepository.findBySearchParams(searchParams); + return new NeighborhoodsMongoBuilder(res).build(); + } +} diff --git a/src/microservice/domain/service/neighborhoods/save-neighborhoods-by-city.service.ts b/src/microservice/domain/service/neighborhoods/save-neighborhoods-by-city.service.ts index 70562e0..2c93afc 100644 --- a/src/microservice/domain/service/neighborhoods/save-neighborhoods-by-city.service.ts +++ b/src/microservice/domain/service/neighborhoods/save-neighborhoods-by-city.service.ts @@ -3,18 +3,37 @@ import { NeighborhoodsByCity } from '../../model/neighborhoods-by-city.model'; import { NeighborhoodsMongoose } from '../../../adapter/repository/neighborhoods/neighborhoods-mongoose.repository'; import { NeighborhoodsPuppeteerBuilder } from '../../../adapter/helper/builder/neighborhoods-puppeteer.builder'; import { SearchNeighborhoods } from '../../model/search/search-neighborhoods.model'; +import { NeighborhoodsService } from './neighborhoods.service'; @Injectable() -export class SaveNeighborhoodsByCityService { - constructor(private readonly mongoRepository: NeighborhoodsMongoose) {} +export class SaveNeighborhoodsByCityService extends NeighborhoodsService { + constructor(mongoRepository: NeighborhoodsMongoose) { + super(mongoRepository); + } async saveNeighborhoodsByCity( neighborhoodsPuppeteer: NeighborhoodsByCity[], searchParams: SearchNeighborhoods ): Promise { - const obj = new NeighborhoodsPuppeteerBuilder(neighborhoodsPuppeteer).build( - searchParams - ); - await this.mongoRepository.insert(obj); + const arrDocument = new NeighborhoodsPuppeteerBuilder( + neighborhoodsPuppeteer + ).build(searchParams); + + arrDocument.forEach(async (item) => { + const responseDB = await this.findNeighborhoodInDatabase( + searchParams, + item.name + ); + + if (responseDB.length === 0) await this.mongoRepository.insert(item); + }); + } + + async findNeighborhoodInDatabase( + searchParams: SearchNeighborhoods, + name: string + ) { + searchParams.name = name; + return this.findInDatabase(searchParams); } } From 16ab21ca5fbc98bcb8e41b1c9f71cf6710e4d4eb Mon Sep 17 00:00:00 2001 From: Maick Speck Date: Fri, 17 Jun 2022 16:34:37 -0300 Subject: [PATCH 06/16] fix unit tests --- .../neighborhoods/neighborhoods.service.ts | 2 +- test/mock/mongoose/mockMongooseModel.ts | 12 +++++++++ .../custom-error-exception.filter.spec.ts | 8 +++++- .../neighborhoods.controller.spec.ts | 20 ++++++++++++--- .../adapter/neighborhoods.module.spec.ts | 19 +++++++++++++- .../get-neighborhoods-by-city.service.spec.ts | 25 +++++++++++++++++++ 6 files changed, 80 insertions(+), 6 deletions(-) create mode 100644 test/mock/mongoose/mockMongooseModel.ts diff --git a/src/microservice/domain/service/neighborhoods/neighborhoods.service.ts b/src/microservice/domain/service/neighborhoods/neighborhoods.service.ts index 480eff3..7b9a658 100644 --- a/src/microservice/domain/service/neighborhoods/neighborhoods.service.ts +++ b/src/microservice/domain/service/neighborhoods/neighborhoods.service.ts @@ -1,4 +1,4 @@ -import { NeighborhoodsMongoBuilder } from 'src/microservice/adapter/helper/builder/neighborhoods-mongo.builder'; +import { NeighborhoodsMongoBuilder } from '../../../adapter/helper/builder/neighborhoods-mongo.builder'; import { NeighborhoodsMongoose } from '../../../adapter/repository/neighborhoods/neighborhoods-mongoose.repository'; import { NeighborhoodsByCity } from '../../model/neighborhoods-by-city.model'; import { SearchNeighborhoods } from '../../model/search/search-neighborhoods.model'; diff --git a/test/mock/mongoose/mockMongooseModel.ts b/test/mock/mongoose/mockMongooseModel.ts new file mode 100644 index 0000000..38bff22 --- /dev/null +++ b/test/mock/mongoose/mockMongooseModel.ts @@ -0,0 +1,12 @@ +export const mockModelMongoose = { + find: () => { + return { exec: jest.fn(() => null) }; + }, + findAll: () => { + return { exec: jest.fn(() => null) }; + }, + create: jest.fn(() => null), + findByIdAndUpdate: () => { + return { exec: jest.fn(() => null) }; + } +}; diff --git a/test/unit/core/error-handling/filter/custom-error-exception.filter.spec.ts b/test/unit/core/error-handling/filter/custom-error-exception.filter.spec.ts index 6123510..38e0b13 100644 --- a/test/unit/core/error-handling/filter/custom-error-exception.filter.spec.ts +++ b/test/unit/core/error-handling/filter/custom-error-exception.filter.spec.ts @@ -10,6 +10,9 @@ import { ExecutionContext } from '@nestjs/common'; import * as sinon from 'sinon'; import { NestFactory } from '@nestjs/core'; import { AppModule } from '../../../../../src/app.module'; +import { Neighborhood } from '../../../../../src/microservice/domain/schemas/neighborhood.schema'; +import { mockModelMongoose } from '../../../../mock/mongoose/mockMongooseModel'; +import { getModelToken } from '@nestjs/mongoose'; describe('CustomErrorExceptionFilter', () => { let sut: CustomErrorExceptionFilter; @@ -21,7 +24,10 @@ describe('CustomErrorExceptionFilter', () => { imports: [ExtensionsModule, FiltersModule], controllers: [], providers: [CustomErrorExceptionFilter] - }).compile(); + }) + .overrideProvider(getModelToken(Neighborhood.name)) + .useValue(mockModelMongoose) + .compile(); sut = app.get(CustomErrorExceptionFilter); server = await NestFactory.create(AppModule); diff --git a/test/unit/microservice/adapter/controller/neighborhoods.controller.spec.ts b/test/unit/microservice/adapter/controller/neighborhoods.controller.spec.ts index 6c6ebfd..58f0cc6 100644 --- a/test/unit/microservice/adapter/controller/neighborhoods.controller.spec.ts +++ b/test/unit/microservice/adapter/controller/neighborhoods.controller.spec.ts @@ -7,16 +7,26 @@ import * as sinon from 'sinon'; import { NeighborhoodsByCity } from '../../../../../src/microservice/domain/model/neighborhoods-by-city.model'; import { ExtensionsModule } from '../../../../../src/microservice/adapter/helper/extensions/exensions.module'; import { GetNeighborhoodsByCityService } from '../../../../../src/microservice/domain/service/neighborhoods/get-neighborhoods-by-city.service'; +import { SaveNeighborhoodsByCityService } from '../../../../../src/microservice/domain/service/neighborhoods/save-neighborhoods-by-city.service'; describe('NeighborhoodsController', () => { let neighborhoodsController: NeighborhoodsController; - const mockNeighborhoodsService = { + const mockGetNeighborhoodsService = { getNeighborhoodsByCity: () => { return; } }; + const mockSaveNeighborhoodsService = { + saveNeighborhoodsByCity: () => { + return; + }, + findNeighborhoodInDatabase: () => { + return []; + } + }; + const mockNeighborhoods: NeighborhoodsByCity[] = [ { name: 'Aires Rodrigues', @@ -41,7 +51,11 @@ describe('NeighborhoodsController', () => { providers: [ { provide: GetNeighborhoodsByCityService, - useFactory: () => mockNeighborhoodsService + useFactory: () => mockGetNeighborhoodsService + }, + { + provide: SaveNeighborhoodsByCityService, + useFactory: () => mockSaveNeighborhoodsService } ] }).compile(); @@ -54,7 +68,7 @@ describe('NeighborhoodsController', () => { describe('NeighborhoodsController', () => { it('should call getNeighborhoodsByCity and return an array', async () => { const guiaMaisStub = sinon - .stub(mockNeighborhoodsService, 'getNeighborhoodsByCity') + .stub(mockGetNeighborhoodsService, 'getNeighborhoodsByCity') .returns(mockNeighborhoods); const actual = await neighborhoodsController.getNeighborhoodsByCity( diff --git a/test/unit/microservice/adapter/neighborhoods.module.spec.ts b/test/unit/microservice/adapter/neighborhoods.module.spec.ts index 8d71f6a..66408b4 100644 --- a/test/unit/microservice/adapter/neighborhoods.module.spec.ts +++ b/test/unit/microservice/adapter/neighborhoods.module.spec.ts @@ -3,6 +3,10 @@ import { NeighborhoodsModule } from '../../../../src/microservice/adapter/neighb import { Test, TestingModule } from '@nestjs/testing'; import { NeighborhoodsController } from '../../../../src/microservice/adapter/controller/neighborhoods.controller'; import { ExtensionsModule } from '../../../../src/microservice/adapter/helper/extensions/exensions.module'; +import { NeighborhoodsMongoose } from '../../../../src/microservice/adapter/repository/neighborhoods/neighborhoods-mongoose.repository'; +import { getModelToken } from '@nestjs/mongoose'; +import { Neighborhood } from '../../../../src/microservice/domain/schemas/neighborhood.schema'; +import { mockModelMongoose } from '../../../mock/mongoose/mockMongooseModel'; describe('NeighborhoodsModule', () => { let sut: NeighborhoodsController; @@ -14,6 +18,15 @@ describe('NeighborhoodsModule', () => { } }; + const mockMongooseRepository = { + findBySearchParams: () => { + return []; + }, + insert: () => { + return; + } + }; + beforeEach(async function () { app = await Test.createTestingModule({ imports: [NeighborhoodsModule, ExtensionsModule], @@ -21,12 +34,16 @@ describe('NeighborhoodsModule', () => { }) .overrideProvider('GuiaMaisRepository') .useValue(mockGuiaMaisRepository) + .overrideProvider(NeighborhoodsMongoose) + .useValue(mockMongooseRepository) + .overrideProvider(getModelToken(Neighborhood.name)) + .useValue(mockModelMongoose) .compile(); sut = app.get(NeighborhoodsController); }); - describe('NeighborhoodsController', function () { + describe('res', function () { it('should call buildResponse for status 200', async function () { const actual = await sut.buildResponse(HttpStatus.OK, {}); expect(actual.status).toBe(HttpStatus.OK); diff --git a/test/unit/microservice/domain/service/neighborhoods/get-neighborhoods-by-city.service.spec.ts b/test/unit/microservice/domain/service/neighborhoods/get-neighborhoods-by-city.service.spec.ts index 1b8a537..16e1840 100644 --- a/test/unit/microservice/domain/service/neighborhoods/get-neighborhoods-by-city.service.spec.ts +++ b/test/unit/microservice/domain/service/neighborhoods/get-neighborhoods-by-city.service.spec.ts @@ -3,6 +3,8 @@ import { GetNeighborhoodsByCityService } from '../../../../../../src/microservic import { expect } from 'chai'; import * as sinon from 'sinon'; import { NeighborhoodsByCity } from '../../../../../../src/microservice/domain/model/neighborhoods-by-city.model'; +import { SaveNeighborhoodsByCityService } from '../../../../../../src/microservice/domain/service/neighborhoods/save-neighborhoods-by-city.service'; +import { NeighborhoodsMongoose } from '../../../../../../src/microservice/adapter/repository/neighborhoods/neighborhoods-mongoose.repository'; describe('GetNeighborhoodsByCityService', () => { let sut: GetNeighborhoodsByCityService; @@ -13,6 +15,21 @@ describe('GetNeighborhoodsByCityService', () => { } }; + const mockMongooseRepository = { + findBySearchParams: () => { + return []; + } + }; + + const mockSaveNeighborhoodsService = { + saveNeighborhoodsByCity: () => { + return; + }, + findNeighborhoodInDatabase: () => { + return []; + } + }; + const mockNeighborhoods: NeighborhoodsByCity[] = [ { name: 'Aires Rodrigues', @@ -33,6 +50,14 @@ describe('GetNeighborhoodsByCityService', () => { provide: 'GuiaMaisRepository', useValue: mockGuiaMaisRepository }, + { + provide: NeighborhoodsMongoose, + useValue: mockMongooseRepository + }, + { + provide: SaveNeighborhoodsByCityService, + useFactory: () => mockSaveNeighborhoodsService + }, GetNeighborhoodsByCityService ] }).compile(); From 3da94234d822b04882b8e0fbac949e757bd0bee1 Mon Sep 17 00:00:00 2001 From: Maick Speck Date: Fri, 17 Jun 2022 19:11:20 -0300 Subject: [PATCH 07/16] improve critical cov tests --- .../controller/neighborhoods.controller.ts | 8 -- .../builder/neighborhoods-mongo.builder.ts | 17 ++- .../neighborhoods-puppeteer.builder.ts | 17 +-- .../adapter/helper/mongodb.helper.ts | 14 --- .../neighborhoods-mongoose.repository.ts | 4 - .../neighborhoods/neighborhoods.service.ts | 8 +- .../save-neighborhoods-by-city.service.ts | 4 +- test/mock/mongoose/mockMongooseModel.ts | 4 +- .../custom-error-exception.filter.spec.ts | 2 + .../transform-response.interceptor.spec.ts | 2 + .../neighborhoods-mongo.builder.spec.ts | 46 ++++++++ .../neighborhoods-puppeteer.builder.spec.ts | 46 ++++++++ .../extensions/object.extension.spec.ts | 1 - .../neighborhoods-mongoose.repository.spec.ts | 102 ++++++++++++++++ .../search/search-neighborhoods.model.spec.ts | 10 ++ .../get-neighborhoods-by-city.service.spec.ts | 29 ++++- ...save-neighborhoods-by-city.service.spec.ts | 109 ++++++++++++++++++ 17 files changed, 369 insertions(+), 54 deletions(-) delete mode 100644 src/microservice/adapter/helper/mongodb.helper.ts create mode 100644 test/unit/microservice/adapter/helper/builder/neighborhoods-mongo.builder.spec.ts create mode 100644 test/unit/microservice/adapter/helper/builder/neighborhoods-puppeteer.builder.spec.ts create mode 100644 test/unit/microservice/adapter/repository/neighborhoods-mongoose.repository.spec.ts create mode 100644 test/unit/microservice/domain/service/neighborhoods/save-neighborhoods-by-city.service.spec.ts diff --git a/src/microservice/adapter/controller/neighborhoods.controller.ts b/src/microservice/adapter/controller/neighborhoods.controller.ts index e0b3146..bca40b2 100644 --- a/src/microservice/adapter/controller/neighborhoods.controller.ts +++ b/src/microservice/adapter/controller/neighborhoods.controller.ts @@ -26,12 +26,4 @@ export class NeighborhoodsController extends AbstractController { ) ); } - - @Get() - async getAll() { - return this.buildResponse( - HttpStatus.OK, - await this.getNeighborhoodsByCityService.getAll() - ); - } } diff --git a/src/microservice/adapter/helper/builder/neighborhoods-mongo.builder.ts b/src/microservice/adapter/helper/builder/neighborhoods-mongo.builder.ts index bfa73c0..a3c0ffd 100644 --- a/src/microservice/adapter/helper/builder/neighborhoods-mongo.builder.ts +++ b/src/microservice/adapter/helper/builder/neighborhoods-mongo.builder.ts @@ -1,17 +1,22 @@ +import { SearchNeighborhoods } from 'src/microservice/domain/model/search/search-neighborhoods.model'; import { NeighborhoodsByCity } from '../../../domain/model/neighborhoods-by-city.model'; import { Neighborhood } from '../../../domain/schemas/neighborhood.schema'; export class NeighborhoodsMongoBuilder { - constructor(private mongoResponse: Neighborhood[]) {} + constructor(private puppeteerResponse: NeighborhoodsByCity[]) {} - build(): NeighborhoodsByCity[] { + build(searchParams: SearchNeighborhoods): Neighborhood[] { const arr = []; - this.mongoResponse.forEach((document) => { - const obj = new NeighborhoodsByCity(); - obj.city = `${document.city.capitalize()} - ${document.state.toUpperCase()}`; - obj.name = document.name; + + this.puppeteerResponse.forEach((item) => { + const obj = new Neighborhood(); + obj.country = searchParams.country; + obj.state = searchParams.state; + obj.city = searchParams.city; + obj.name = item.name; arr.push(obj); }); + return arr; } } diff --git a/src/microservice/adapter/helper/builder/neighborhoods-puppeteer.builder.ts b/src/microservice/adapter/helper/builder/neighborhoods-puppeteer.builder.ts index abddbef..0496e82 100644 --- a/src/microservice/adapter/helper/builder/neighborhoods-puppeteer.builder.ts +++ b/src/microservice/adapter/helper/builder/neighborhoods-puppeteer.builder.ts @@ -1,22 +1,17 @@ -import { SearchNeighborhoods } from 'src/microservice/domain/model/search/search-neighborhoods.model'; import { NeighborhoodsByCity } from '../../../domain/model/neighborhoods-by-city.model'; import { Neighborhood } from '../../../domain/schemas/neighborhood.schema'; export class NeighborhoodsPuppeteerBuilder { - constructor(private puppeteerResponse: NeighborhoodsByCity[]) {} + constructor(private mongoResponse: Neighborhood[]) {} - build(searchParams: SearchNeighborhoods): Neighborhood[] { + build(): NeighborhoodsByCity[] { const arr = []; - - this.puppeteerResponse.forEach((item) => { - const obj = new Neighborhood(); - obj.country = searchParams.country; - obj.state = searchParams.state; - obj.city = searchParams.city; - obj.name = item.name; + this.mongoResponse.forEach((document) => { + const obj = new NeighborhoodsByCity(); + obj.city = `${document.city.capitalize()} - ${document.state.toUpperCase()}`; + obj.name = document.name; arr.push(obj); }); - return arr; } } diff --git a/src/microservice/adapter/helper/mongodb.helper.ts b/src/microservice/adapter/helper/mongodb.helper.ts deleted file mode 100644 index 82e0e8f..0000000 --- a/src/microservice/adapter/helper/mongodb.helper.ts +++ /dev/null @@ -1,14 +0,0 @@ -export class MongoDBHelper { - static generateObjectID(length = 16): string { - const timestamp = ((new Date().getTime() / 1000) | 0).toString(length); - return ( - timestamp + - 'x' - .repeat(length) - .replace(/[x]/g, function () { - return ((Math.random() * length) | 0).toString(length); - }) - .toLowerCase() - ); - } -} diff --git a/src/microservice/adapter/repository/neighborhoods/neighborhoods-mongoose.repository.ts b/src/microservice/adapter/repository/neighborhoods/neighborhoods-mongoose.repository.ts index c4197a8..7cfbad2 100644 --- a/src/microservice/adapter/repository/neighborhoods/neighborhoods-mongoose.repository.ts +++ b/src/microservice/adapter/repository/neighborhoods/neighborhoods-mongoose.repository.ts @@ -17,10 +17,6 @@ export class NeighborhoodsMongoose extends MongooseRepository { super(model); } - async findAll(): Promise { - return await this.model.find().select({ _id: 0 }).lean().exec(); - } - async findBySearchParams( searchParams: SearchNeighborhoods ): Promise { diff --git a/src/microservice/domain/service/neighborhoods/neighborhoods.service.ts b/src/microservice/domain/service/neighborhoods/neighborhoods.service.ts index 7b9a658..bb04457 100644 --- a/src/microservice/domain/service/neighborhoods/neighborhoods.service.ts +++ b/src/microservice/domain/service/neighborhoods/neighborhoods.service.ts @@ -1,4 +1,4 @@ -import { NeighborhoodsMongoBuilder } from '../../../adapter/helper/builder/neighborhoods-mongo.builder'; +import { NeighborhoodsPuppeteerBuilder } from '../../../adapter/helper/builder/neighborhoods-puppeteer.builder'; import { NeighborhoodsMongoose } from '../../../adapter/repository/neighborhoods/neighborhoods-mongoose.repository'; import { NeighborhoodsByCity } from '../../model/neighborhoods-by-city.model'; import { SearchNeighborhoods } from '../../model/search/search-neighborhoods.model'; @@ -6,14 +6,10 @@ import { SearchNeighborhoods } from '../../model/search/search-neighborhoods.mod export abstract class NeighborhoodsService { constructor(protected readonly mongoRepository: NeighborhoodsMongoose) {} - async getAll() { - return this.mongoRepository.findAll(); - } - async findInDatabase( searchParams: SearchNeighborhoods ): Promise { const res = await this.mongoRepository.findBySearchParams(searchParams); - return new NeighborhoodsMongoBuilder(res).build(); + return new NeighborhoodsPuppeteerBuilder(res).build(); } } diff --git a/src/microservice/domain/service/neighborhoods/save-neighborhoods-by-city.service.ts b/src/microservice/domain/service/neighborhoods/save-neighborhoods-by-city.service.ts index 2c93afc..aaf183d 100644 --- a/src/microservice/domain/service/neighborhoods/save-neighborhoods-by-city.service.ts +++ b/src/microservice/domain/service/neighborhoods/save-neighborhoods-by-city.service.ts @@ -1,7 +1,7 @@ import { Injectable } from '@nestjs/common'; import { NeighborhoodsByCity } from '../../model/neighborhoods-by-city.model'; import { NeighborhoodsMongoose } from '../../../adapter/repository/neighborhoods/neighborhoods-mongoose.repository'; -import { NeighborhoodsPuppeteerBuilder } from '../../../adapter/helper/builder/neighborhoods-puppeteer.builder'; +import { NeighborhoodsMongoBuilder } from '../../../adapter/helper/builder/neighborhoods-mongo.builder'; import { SearchNeighborhoods } from '../../model/search/search-neighborhoods.model'; import { NeighborhoodsService } from './neighborhoods.service'; @@ -15,7 +15,7 @@ export class SaveNeighborhoodsByCityService extends NeighborhoodsService { neighborhoodsPuppeteer: NeighborhoodsByCity[], searchParams: SearchNeighborhoods ): Promise { - const arrDocument = new NeighborhoodsPuppeteerBuilder( + const arrDocument = new NeighborhoodsMongoBuilder( neighborhoodsPuppeteer ).build(searchParams); diff --git a/test/mock/mongoose/mockMongooseModel.ts b/test/mock/mongoose/mockMongooseModel.ts index 38bff22..a66452e 100644 --- a/test/mock/mongoose/mockMongooseModel.ts +++ b/test/mock/mongoose/mockMongooseModel.ts @@ -1,6 +1,8 @@ export const mockModelMongoose = { find: () => { - return { exec: jest.fn(() => null) }; + return { + exec: jest.fn(() => null) + }; }, findAll: () => { return { exec: jest.fn(() => null) }; diff --git a/test/unit/core/error-handling/filter/custom-error-exception.filter.spec.ts b/test/unit/core/error-handling/filter/custom-error-exception.filter.spec.ts index 38e0b13..fa5a79f 100644 --- a/test/unit/core/error-handling/filter/custom-error-exception.filter.spec.ts +++ b/test/unit/core/error-handling/filter/custom-error-exception.filter.spec.ts @@ -14,6 +14,8 @@ import { Neighborhood } from '../../../../../src/microservice/domain/schemas/nei import { mockModelMongoose } from '../../../../mock/mongoose/mockMongooseModel'; import { getModelToken } from '@nestjs/mongoose'; +jest.setTimeout(22000); + describe('CustomErrorExceptionFilter', () => { let sut: CustomErrorExceptionFilter; let app: TestingModule; diff --git a/test/unit/core/http/transform-response.interceptor.spec.ts b/test/unit/core/http/transform-response.interceptor.spec.ts index 19a5d9b..278488d 100644 --- a/test/unit/core/http/transform-response.interceptor.spec.ts +++ b/test/unit/core/http/transform-response.interceptor.spec.ts @@ -16,6 +16,8 @@ import { CustomResponse } from '../../../../src/core/interface/custom-response.i import { of } from 'rxjs'; import * as sinon from 'sinon'; +jest.setTimeout(22000); + describe('TransformResponseInterceptor ', () => { let app: INestApplication; let mockAdapter; diff --git a/test/unit/microservice/adapter/helper/builder/neighborhoods-mongo.builder.spec.ts b/test/unit/microservice/adapter/helper/builder/neighborhoods-mongo.builder.spec.ts new file mode 100644 index 0000000..7d400e7 --- /dev/null +++ b/test/unit/microservice/adapter/helper/builder/neighborhoods-mongo.builder.spec.ts @@ -0,0 +1,46 @@ +import '../../../../../../src/microservice/adapter/helper/extensions/exensions.module'; +import { expect } from 'chai'; +import { NeighborhoodsMongoBuilder } from '../../../../../../src/microservice/adapter/helper/builder/neighborhoods-mongo.builder'; +import { SearchNeighborhoods } from '../../../../../../src/microservice/domain/model/search/search-neighborhoods.model'; +import { Neighborhood } from '../../../../../../src/microservice/domain/schemas/neighborhood.schema'; + +const mockNeighborhoodsByCity = [ + { + name: 'Harlem', + city: 'New York City - NY' + }, + { + name: `Hell's Kitchen`, + city: 'New York City - NY' + } +]; + +const mockMongoNeighborhoods = () => { + const arr = []; + const item1 = new Neighborhood(); + item1.country = 'USA'; + item1.state = 'NY'; + item1.city = 'New York City'; + item1.name = 'Harlem'; + arr.push(item1); + + const item2 = new Neighborhood(); + item2.country = 'USA'; + item2.state = 'NY'; + item2.city = 'New York City'; + item2.name = `Hell's Kitchen`; + arr.push(item2); + + return arr; +}; + +describe('NeighborhoodsMongoBuilder ', () => { + it('Should instanciate NeighborhoodsMongoBuilder and build correctly', function () { + const nestBuilder = new NeighborhoodsMongoBuilder(mockNeighborhoodsByCity); + const mockSearch = new SearchNeighborhoods('USA', 'NY', 'New York City'); + const actual = nestBuilder.build(mockSearch); + expect(JSON.stringify(actual)).to.be.equal( + JSON.stringify(mockMongoNeighborhoods()) + ); + }); +}); diff --git a/test/unit/microservice/adapter/helper/builder/neighborhoods-puppeteer.builder.spec.ts b/test/unit/microservice/adapter/helper/builder/neighborhoods-puppeteer.builder.spec.ts new file mode 100644 index 0000000..81393a2 --- /dev/null +++ b/test/unit/microservice/adapter/helper/builder/neighborhoods-puppeteer.builder.spec.ts @@ -0,0 +1,46 @@ +import '../../../../../../src/microservice/adapter/helper/extensions/exensions.module'; +import { expect } from 'chai'; +import { NeighborhoodsPuppeteerBuilder } from '../../../../../../src/microservice/adapter/helper/builder/neighborhoods-puppeteer.builder'; +import { Neighborhood } from '../../../../../../src/microservice/domain/schemas/neighborhood.schema'; + +const mockNeighborhoodsByCity = [ + { + city: 'New York City - NY', + name: 'Harlem' + }, + { + city: 'New York City - NY', + name: `Hell's Kitchen` + } +]; + +const mockMongoNeighborhoods = () => { + const arr = []; + const item1 = new Neighborhood(); + item1.country = 'USA'; + item1.state = 'NY'; + item1.city = 'New York City'; + item1.name = 'Harlem'; + arr.push(item1); + + const item2 = new Neighborhood(); + item2.country = 'USA'; + item2.state = 'NY'; + item2.city = 'New York City'; + item2.name = `Hell's Kitchen`; + arr.push(item2); + + return arr; +}; + +describe('NeighborhoodsPuppeteerBuilder ', () => { + it('Should instanciate NeighborhoodsPuppeteerBuilder and build correctly', function () { + const nestBuilder = new NeighborhoodsPuppeteerBuilder( + mockMongoNeighborhoods() + ); + const actual = nestBuilder.build(); + expect(JSON.stringify(actual)).to.be.equal( + JSON.stringify(mockNeighborhoodsByCity) + ); + }); +}); diff --git a/test/unit/microservice/adapter/helper/extensions/object.extension.spec.ts b/test/unit/microservice/adapter/helper/extensions/object.extension.spec.ts index f7a0854..53bedea 100644 --- a/test/unit/microservice/adapter/helper/extensions/object.extension.spec.ts +++ b/test/unit/microservice/adapter/helper/extensions/object.extension.spec.ts @@ -1,7 +1,6 @@ import '../../../../../../src/microservice/adapter/helper/extensions/exensions.module'; import { expect } from 'chai'; import { SearchNeighborhoods } from '../../../../../../src/microservice/domain/model/search/search-neighborhoods.model'; -import { EmptyPropException } from '../../../../../../src/core/error-handling/exception/empty-prop.exception'; describe('object.extension', () => { describe('getMethods', function () { diff --git a/test/unit/microservice/adapter/repository/neighborhoods-mongoose.repository.spec.ts b/test/unit/microservice/adapter/repository/neighborhoods-mongoose.repository.spec.ts new file mode 100644 index 0000000..9348538 --- /dev/null +++ b/test/unit/microservice/adapter/repository/neighborhoods-mongoose.repository.spec.ts @@ -0,0 +1,102 @@ +import { Test, TestingModule } from '@nestjs/testing'; +import { expect } from 'chai'; +import * as sinon from 'sinon'; +import { SearchNeighborhoods } from '../../../../../src/microservice/domain/model/search/search-neighborhoods.model'; +import { ExtensionsModule } from '../../../../../src/microservice/adapter/helper/extensions/exensions.module'; +import { NeighborhoodsMongoose } from '../../../../../src/microservice/adapter/repository/neighborhoods/neighborhoods-mongoose.repository'; +import { getModelToken } from '@nestjs/mongoose'; +import { Neighborhood } from '../../../../../src/microservice/domain/schemas/neighborhood.schema'; +import { mockModelMongoose } from '../../../../mock/mongoose/mockMongooseModel'; + +jest.useFakeTimers(); +jest.setTimeout(50000); + +describe('NeighborhoodsMongoose', () => { + let sut: NeighborhoodsMongoose; + let app: TestingModule; + + const mockNeighborhoods = () => { + const arr = []; + const item1 = new Neighborhood(); + item1.country = 'USA'; + item1.state = 'NJ'; + item1.city = 'Gotham City'; + item1.name = 'Brideshead'; + arr.push(item1); + + const item2 = new Neighborhood(); + item2.country = 'USA'; + item2.state = 'NJ'; + item2.city = 'Gotham City'; + item2.name = `Bristol Township`; + arr.push(item2); + + return arr; + }; + + const mockFindNeighborhoods = { + select: jest.fn(() => { + return { + lean: jest.fn(() => { + return { + exec: jest.fn(() => mockNeighborhoods()) + }; + }) + }; + }) + }; + + beforeEach(async () => { + app = await Test.createTestingModule({ + imports: [ExtensionsModule], + controllers: [], + providers: [ + NeighborhoodsMongoose, + { + provide: getModelToken(Neighborhood.name), + useValue: mockModelMongoose + } + ] + }).compile(); + + sut = app.get(NeighborhoodsMongoose); + }); + + afterEach(async () => { + await app.close(); + }); + + describe('findBySearchParams', () => { + it('should call findBySearchParams and return an array', async () => { + const mockSearchParams = new SearchNeighborhoods( + 'USA', + 'NJ', + 'Gotham City' + ); + + const findManyStub = sinon + .stub(mockModelMongoose, 'find') + .returns(mockFindNeighborhoods); + + const actual = await sut.findBySearchParams(mockSearchParams); + + expect(actual).to.be.an('array').that.is.not.empty; + + findManyStub.restore(); + }); + }); + + describe('insert', () => { + it('should call insert and call model.create with the correct params', async () => { + const createSpy = sinon.spy(mockModelMongoose, 'create'); + + const doc = new Neighborhood(); + + await sut.insert(doc); + + sinon.assert.calledOnceWithExactly(createSpy, doc); + + createSpy.restore(); + }); + }); +}); diff --git a/test/unit/microservice/domain/model/search/search-neighborhoods.model.spec.ts b/test/unit/microservice/domain/model/search/search-neighborhoods.model.spec.ts index 815a4b6..14093d1 100644 --- a/test/unit/microservice/domain/model/search/search-neighborhoods.model.spec.ts +++ b/test/unit/microservice/domain/model/search/search-neighborhoods.model.spec.ts @@ -9,4 +9,14 @@ describe('SearchNeighborhoods', () => { expect(model.state).to.be.equal('sc'); expect(model.city).to.be.equal('praia grande'); }); + + it('should instance SearchNeighborhoods, setName and return the object with the correct properties', async () => { + const model = new SearchNeighborhoods('brasil', 'sc', 'praia grande'); + model.setName('Vila Rosa'); + + expect(model.country).to.be.equal('brasil'); + expect(model.state).to.be.equal('sc'); + expect(model.city).to.be.equal('praia grande'); + expect(model.name).to.be.equal('Vila Rosa'); + }); }); diff --git a/test/unit/microservice/domain/service/neighborhoods/get-neighborhoods-by-city.service.spec.ts b/test/unit/microservice/domain/service/neighborhoods/get-neighborhoods-by-city.service.spec.ts index 16e1840..dc3be53 100644 --- a/test/unit/microservice/domain/service/neighborhoods/get-neighborhoods-by-city.service.spec.ts +++ b/test/unit/microservice/domain/service/neighborhoods/get-neighborhoods-by-city.service.spec.ts @@ -5,6 +5,8 @@ import * as sinon from 'sinon'; import { NeighborhoodsByCity } from '../../../../../../src/microservice/domain/model/neighborhoods-by-city.model'; import { SaveNeighborhoodsByCityService } from '../../../../../../src/microservice/domain/service/neighborhoods/save-neighborhoods-by-city.service'; import { NeighborhoodsMongoose } from '../../../../../../src/microservice/adapter/repository/neighborhoods/neighborhoods-mongoose.repository'; +import { Neighborhood } from '../../../../../../src/microservice/domain/schemas/neighborhood.schema'; +import '../../../../../../src/microservice/adapter/helper/extensions/exensions.module'; describe('GetNeighborhoodsByCityService', () => { let sut: GetNeighborhoodsByCityService; @@ -30,6 +32,13 @@ describe('GetNeighborhoodsByCityService', () => { } }; + const mockMongoNeighborhoods = () => { + const arr = []; + const item1 = new Neighborhood(); + arr.push(item1); + return arr; + }; + const mockNeighborhoods: NeighborhoodsByCity[] = [ { name: 'Aires Rodrigues', @@ -66,7 +75,7 @@ describe('GetNeighborhoodsByCityService', () => { }); describe('GetNeighborhoodsByCityService', () => { - it('should call getNeighborhoodsByCity and return an array', async () => { + it('should call getNeighborhoodsByCity and return an array by puppeteer', async () => { const guiaMaisStub = sinon .stub(mockGuiaMaisRepository, 'getNeighborhoodsByCity') .returns(mockNeighborhoods); @@ -82,5 +91,23 @@ describe('GetNeighborhoodsByCityService', () => { guiaMaisStub.restore(); }); + + it('should call getNeighborhoodsByCity and return an array by mongodb', async () => { + const mongoFindStub = sinon + .stub(sut, 'findInDatabase') + .returns(mockMongoNeighborhoods()); + + const actual = await sut.getNeighborhoodsByCity( + 'brasil', + 'sc', + 'orleans' + ); + + expect(JSON.stringify(actual)).to.be.equal( + JSON.stringify(mockMongoNeighborhoods()) + ); + + mongoFindStub.restore(); + }); }); }); diff --git a/test/unit/microservice/domain/service/neighborhoods/save-neighborhoods-by-city.service.spec.ts b/test/unit/microservice/domain/service/neighborhoods/save-neighborhoods-by-city.service.spec.ts new file mode 100644 index 0000000..f7188ca --- /dev/null +++ b/test/unit/microservice/domain/service/neighborhoods/save-neighborhoods-by-city.service.spec.ts @@ -0,0 +1,109 @@ +import { Test, TestingModule } from '@nestjs/testing'; +import * as sinon from 'sinon'; +import { SaveNeighborhoodsByCityService } from '../../../../../../src/microservice/domain/service/neighborhoods/save-neighborhoods-by-city.service'; +import { NeighborhoodsMongoose } from '../../../../../../src/microservice/adapter/repository/neighborhoods/neighborhoods-mongoose.repository'; +import { ExtensionsModule } from '../../../../../../src/microservice/adapter/helper/extensions/exensions.module'; +import { SearchNeighborhoods } from '../../../../../../src/microservice/domain/model/search/search-neighborhoods.model'; +import { NeighborhoodsByCity } from '../../../../../../src/microservice/domain/model/neighborhoods-by-city.model'; +import { Neighborhood } from '../../../../../../src/microservice/domain/schemas/neighborhood.schema'; + +describe('SaveNeighborhoodsByCityService', () => { + let sut: SaveNeighborhoodsByCityService; + + const mockNeighborhoods: NeighborhoodsByCity[] = [ + { + name: 'Aires Rodrigues', + city: 'Orleans-SC' + }, + { + name: 'Alto ParanĂ¡', + city: 'Orleans-SC' + } + ]; + + const mockNeighborhoodMongooseRepository = { + findBySearchParams: () => { + return []; + }, + insert: () => { + return; + } + }; + + const mockMongoNeighborhoods = () => { + const arr = []; + const item1 = new Neighborhood(); + arr.push(item1); + return arr; + }; + + beforeEach(async () => { + const app: TestingModule = await Test.createTestingModule({ + imports: [ExtensionsModule], + controllers: [], + providers: [ + { + provide: NeighborhoodsMongoose, + useValue: mockNeighborhoodMongooseRepository + }, + SaveNeighborhoodsByCityService + ] + }).compile(); + + sut = app.get( + SaveNeighborhoodsByCityService + ); + }); + + describe('saveNeighborhoodsByCity', () => { + it('should call saveNeighborhoodsByCity and call insert twice', async () => { + const findStub = sinon + .stub(sut, 'findNeighborhoodInDatabase') + .returns([]); + + const insertSpy = sinon.spy(mockNeighborhoodMongooseRepository, 'insert'); + + const searchParams = new SearchNeighborhoods('brasil', 'sc', 'orleans'); + + await sut.saveNeighborhoodsByCity(mockNeighborhoods, searchParams); + + sinon.assert.calledTwice(insertSpy); + + findStub.restore(); + insertSpy.restore(); + }); + + it('should call saveNeighborhoodsByCity and not call insert', async () => { + const findStub = sinon + .stub(sut, 'findNeighborhoodInDatabase') + .returns(mockMongoNeighborhoods()); + + const insertSpy = sinon.spy(mockNeighborhoodMongooseRepository, 'insert'); + + const searchParams = new SearchNeighborhoods('brasil', 'sc', 'orleans'); + + await sut.saveNeighborhoodsByCity(mockNeighborhoods, searchParams); + + sinon.assert.notCalled(insertSpy); + + findStub.restore(); + insertSpy.restore(); + }); + }); + + describe('findNeighborhoodInDatabase', () => { + it('should call saveNeighborhoodsByCity and call insert twice', async () => { + const findInDatabaseStub = sinon.stub(sut, 'findInDatabase').returns(); + + const searchParams = new SearchNeighborhoods('brasil', 'sc', 'orleans'); + + await sut.findNeighborhoodInDatabase(searchParams, 'Alto ParanĂ¡'); + + searchParams.name = 'Alto ParanĂ¡'; + + sinon.assert.calledOnceWithExactly(findInDatabaseStub, searchParams); + + findInDatabaseStub.restore(); + }); + }); +}); From 9fd6b9aeaabf169c4d548f7986abd0e9ce4092d3 Mon Sep 17 00:00:00 2001 From: Maick Speck Date: Fri, 17 Jun 2022 19:28:23 -0300 Subject: [PATCH 08/16] logger --- .../domain/service/abstract-service.service.ts | 5 +++++ .../neighborhoods/get-neighborhoods-by-city.service.ts | 5 +++++ .../domain/service/neighborhoods/neighborhoods.service.ts | 8 ++++++-- .../neighborhoods/save-neighborhoods-by-city.service.ts | 5 ++++- 4 files changed, 20 insertions(+), 3 deletions(-) create mode 100644 src/microservice/domain/service/abstract-service.service.ts diff --git a/src/microservice/domain/service/abstract-service.service.ts b/src/microservice/domain/service/abstract-service.service.ts new file mode 100644 index 0000000..8e25900 --- /dev/null +++ b/src/microservice/domain/service/abstract-service.service.ts @@ -0,0 +1,5 @@ +import { Logger } from '@nestjs/common'; + +export abstract class AbstractService { + protected readonly logger: Logger = new Logger(this.constructor.name); +} diff --git a/src/microservice/domain/service/neighborhoods/get-neighborhoods-by-city.service.ts b/src/microservice/domain/service/neighborhoods/get-neighborhoods-by-city.service.ts index 08839c9..68bf715 100644 --- a/src/microservice/domain/service/neighborhoods/get-neighborhoods-by-city.service.ts +++ b/src/microservice/domain/service/neighborhoods/get-neighborhoods-by-city.service.ts @@ -27,6 +27,7 @@ export class GetNeighborhoodsByCityService extends NeighborhoodsService { const resMongo = await this.findInDatabase(searchParams); if (!resMongo.length) { + this.logger.log('Searching by puppeteer...'); const resPuppeteer = await this.guiaMaisRepository.getNeighborhoodsByCity( searchParams ); @@ -36,9 +37,13 @@ export class GetNeighborhoodsByCityService extends NeighborhoodsService { searchParams ); + this.logger.log('Returning Puppeteer response...'); + return resPuppeteer; } + this.logger.log('Returning MongoDB response...'); + return resMongo; } } diff --git a/src/microservice/domain/service/neighborhoods/neighborhoods.service.ts b/src/microservice/domain/service/neighborhoods/neighborhoods.service.ts index bb04457..9e3ec1b 100644 --- a/src/microservice/domain/service/neighborhoods/neighborhoods.service.ts +++ b/src/microservice/domain/service/neighborhoods/neighborhoods.service.ts @@ -2,13 +2,17 @@ import { NeighborhoodsPuppeteerBuilder } from '../../../adapter/helper/builder/n import { NeighborhoodsMongoose } from '../../../adapter/repository/neighborhoods/neighborhoods-mongoose.repository'; import { NeighborhoodsByCity } from '../../model/neighborhoods-by-city.model'; import { SearchNeighborhoods } from '../../model/search/search-neighborhoods.model'; +import { AbstractService } from '../abstract-service.service'; -export abstract class NeighborhoodsService { - constructor(protected readonly mongoRepository: NeighborhoodsMongoose) {} +export abstract class NeighborhoodsService extends AbstractService { + constructor(protected readonly mongoRepository: NeighborhoodsMongoose) { + super(); + } async findInDatabase( searchParams: SearchNeighborhoods ): Promise { + this.logger.log('Searching in database...'); const res = await this.mongoRepository.findBySearchParams(searchParams); return new NeighborhoodsPuppeteerBuilder(res).build(); } diff --git a/src/microservice/domain/service/neighborhoods/save-neighborhoods-by-city.service.ts b/src/microservice/domain/service/neighborhoods/save-neighborhoods-by-city.service.ts index aaf183d..8566e41 100644 --- a/src/microservice/domain/service/neighborhoods/save-neighborhoods-by-city.service.ts +++ b/src/microservice/domain/service/neighborhoods/save-neighborhoods-by-city.service.ts @@ -25,7 +25,10 @@ export class SaveNeighborhoodsByCityService extends NeighborhoodsService { item.name ); - if (responseDB.length === 0) await this.mongoRepository.insert(item); + if (responseDB.length === 0) { + this.logger.log(`Saving neighborhood '${item.name}'...`); + await this.mongoRepository.insert(item); + } }); } From 3c1f9772a7befa54f8d68b82aaa6e2b36496be41 Mon Sep 17 00:00:00 2001 From: Maick Speck Date: Fri, 17 Jun 2022 19:33:51 -0300 Subject: [PATCH 09/16] readme --- README.md | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/README.md b/README.md index 69c3423..a6b4ee4 100644 --- a/README.md +++ b/README.md @@ -7,6 +7,15 @@

This project use NestJS, a progressive Node.js framework for building efficient and scalable server-side applications.

+## Technologies + +
    +
  • NestJS
  • +
  • NodeJS
  • +
  • Puppeteer
  • +
  • MongoDB
  • +
+ ## Description API to get Places by Local Names. From ce8408395210adf3dd45a6c102f797fc748fd40e Mon Sep 17 00:00:00 2001 From: Maick Speck Date: Fri, 17 Jun 2022 19:43:19 -0300 Subject: [PATCH 10/16] timeout exception --- .../error-handling/filter/custom-error-exception.filter.spec.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/unit/core/error-handling/filter/custom-error-exception.filter.spec.ts b/test/unit/core/error-handling/filter/custom-error-exception.filter.spec.ts index fa5a79f..94805f0 100644 --- a/test/unit/core/error-handling/filter/custom-error-exception.filter.spec.ts +++ b/test/unit/core/error-handling/filter/custom-error-exception.filter.spec.ts @@ -14,7 +14,7 @@ import { Neighborhood } from '../../../../../src/microservice/domain/schemas/nei import { mockModelMongoose } from '../../../../mock/mongoose/mockMongooseModel'; import { getModelToken } from '@nestjs/mongoose'; -jest.setTimeout(22000); +jest.setTimeout(50000); describe('CustomErrorExceptionFilter', () => { let sut: CustomErrorExceptionFilter; From 740869253f251f04b5432a10262a82f5963c31ce Mon Sep 17 00:00:00 2001 From: Maick Speck Date: Fri, 17 Jun 2022 20:08:34 -0300 Subject: [PATCH 11/16] fix mock mongo connection --- .../custom-error-exception.filter.spec.ts | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/test/unit/core/error-handling/filter/custom-error-exception.filter.spec.ts b/test/unit/core/error-handling/filter/custom-error-exception.filter.spec.ts index 94805f0..080952f 100644 --- a/test/unit/core/error-handling/filter/custom-error-exception.filter.spec.ts +++ b/test/unit/core/error-handling/filter/custom-error-exception.filter.spec.ts @@ -14,6 +14,22 @@ import { Neighborhood } from '../../../../../src/microservice/domain/schemas/nei import { mockModelMongoose } from '../../../../mock/mongoose/mockMongooseModel'; import { getModelToken } from '@nestjs/mongoose'; +jest.mock('mongoose', () => { + return { + createConnection: jest.fn(() => { + return { + asPromise: jest.fn(() => { + return { + model: jest.fn(), + close: jest.fn() + }; + }) + }; + }), + Schema: jest.fn() + }; +}); + jest.setTimeout(50000); describe('CustomErrorExceptionFilter', () => { @@ -32,6 +48,7 @@ describe('CustomErrorExceptionFilter', () => { .compile(); sut = app.get(CustomErrorExceptionFilter); + server = await NestFactory.create(AppModule); await server.init(); }); From 5ef8f10f89ea7243ad13b90858392779a2b3e985 Mon Sep 17 00:00:00 2001 From: Maick Speck Date: Fri, 17 Jun 2022 20:22:47 -0300 Subject: [PATCH 12/16] mock jest mongoose --- test/mock/mongoose/mock-mongoose.ts | 30 +++++++++++++++++++ test/mock/mongoose/mockMongooseModel.ts | 14 --------- .../custom-error-exception.filter.spec.ts | 21 ++----------- .../transform-response.interceptor.spec.ts | 2 ++ .../adapter/neighborhoods.module.spec.ts | 2 +- .../neighborhoods-mongoose.repository.spec.ts | 2 +- 6 files changed, 37 insertions(+), 34 deletions(-) create mode 100644 test/mock/mongoose/mock-mongoose.ts delete mode 100644 test/mock/mongoose/mockMongooseModel.ts diff --git a/test/mock/mongoose/mock-mongoose.ts b/test/mock/mongoose/mock-mongoose.ts new file mode 100644 index 0000000..74982ea --- /dev/null +++ b/test/mock/mongoose/mock-mongoose.ts @@ -0,0 +1,30 @@ +export const mockModelMongoose = { + find: () => { + return { + exec: jest.fn(() => null) + }; + }, + findAll: () => { + return { exec: jest.fn(() => null) }; + }, + create: jest.fn(() => null), + findByIdAndUpdate: () => { + return { exec: jest.fn(() => null) }; + } +}; + +jest.mock('mongoose', () => { + return { + createConnection: jest.fn(() => { + return { + asPromise: jest.fn(() => { + return { + model: jest.fn(), + close: jest.fn() + }; + }) + }; + }), + Schema: jest.fn() + }; +}); diff --git a/test/mock/mongoose/mockMongooseModel.ts b/test/mock/mongoose/mockMongooseModel.ts deleted file mode 100644 index a66452e..0000000 --- a/test/mock/mongoose/mockMongooseModel.ts +++ /dev/null @@ -1,14 +0,0 @@ -export const mockModelMongoose = { - find: () => { - return { - exec: jest.fn(() => null) - }; - }, - findAll: () => { - return { exec: jest.fn(() => null) }; - }, - create: jest.fn(() => null), - findByIdAndUpdate: () => { - return { exec: jest.fn(() => null) }; - } -}; diff --git a/test/unit/core/error-handling/filter/custom-error-exception.filter.spec.ts b/test/unit/core/error-handling/filter/custom-error-exception.filter.spec.ts index 080952f..e571d9f 100644 --- a/test/unit/core/error-handling/filter/custom-error-exception.filter.spec.ts +++ b/test/unit/core/error-handling/filter/custom-error-exception.filter.spec.ts @@ -11,26 +11,11 @@ import * as sinon from 'sinon'; import { NestFactory } from '@nestjs/core'; import { AppModule } from '../../../../../src/app.module'; import { Neighborhood } from '../../../../../src/microservice/domain/schemas/neighborhood.schema'; -import { mockModelMongoose } from '../../../../mock/mongoose/mockMongooseModel'; +import { mockModelMongoose } from '../../../../mock/mongoose/mock-mongoose'; import { getModelToken } from '@nestjs/mongoose'; +import '../../../../mock/mongoose/mock-mongoose.ts'; -jest.mock('mongoose', () => { - return { - createConnection: jest.fn(() => { - return { - asPromise: jest.fn(() => { - return { - model: jest.fn(), - close: jest.fn() - }; - }) - }; - }), - Schema: jest.fn() - }; -}); - -jest.setTimeout(50000); +jest.setTimeout(25000); describe('CustomErrorExceptionFilter', () => { let sut: CustomErrorExceptionFilter; diff --git a/test/unit/core/http/transform-response.interceptor.spec.ts b/test/unit/core/http/transform-response.interceptor.spec.ts index 278488d..c443fa1 100644 --- a/test/unit/core/http/transform-response.interceptor.spec.ts +++ b/test/unit/core/http/transform-response.interceptor.spec.ts @@ -16,6 +16,8 @@ import { CustomResponse } from '../../../../src/core/interface/custom-response.i import { of } from 'rxjs'; import * as sinon from 'sinon'; +import '../../../mock/mongoose/mock-mongoose.ts'; + jest.setTimeout(22000); describe('TransformResponseInterceptor ', () => { diff --git a/test/unit/microservice/adapter/neighborhoods.module.spec.ts b/test/unit/microservice/adapter/neighborhoods.module.spec.ts index 66408b4..3a3b0c0 100644 --- a/test/unit/microservice/adapter/neighborhoods.module.spec.ts +++ b/test/unit/microservice/adapter/neighborhoods.module.spec.ts @@ -6,7 +6,7 @@ import { ExtensionsModule } from '../../../../src/microservice/adapter/helper/ex import { NeighborhoodsMongoose } from '../../../../src/microservice/adapter/repository/neighborhoods/neighborhoods-mongoose.repository'; import { getModelToken } from '@nestjs/mongoose'; import { Neighborhood } from '../../../../src/microservice/domain/schemas/neighborhood.schema'; -import { mockModelMongoose } from '../../../mock/mongoose/mockMongooseModel'; +import { mockModelMongoose } from '../../../mock/mongoose/mock-mongoose'; describe('NeighborhoodsModule', () => { let sut: NeighborhoodsController; diff --git a/test/unit/microservice/adapter/repository/neighborhoods-mongoose.repository.spec.ts b/test/unit/microservice/adapter/repository/neighborhoods-mongoose.repository.spec.ts index 9348538..9f498ac 100644 --- a/test/unit/microservice/adapter/repository/neighborhoods-mongoose.repository.spec.ts +++ b/test/unit/microservice/adapter/repository/neighborhoods-mongoose.repository.spec.ts @@ -6,7 +6,7 @@ import { ExtensionsModule } from '../../../../../src/microservice/adapter/helper import { NeighborhoodsMongoose } from '../../../../../src/microservice/adapter/repository/neighborhoods/neighborhoods-mongoose.repository'; import { getModelToken } from '@nestjs/mongoose'; import { Neighborhood } from '../../../../../src/microservice/domain/schemas/neighborhood.schema'; -import { mockModelMongoose } from '../../../../mock/mongoose/mockMongooseModel'; +import { mockModelMongoose } from '../../../../mock/mongoose/mock-mongoose'; jest.useFakeTimers(); jest.setTimeout(50000); From a04793041bb94289b030e4ad96992a84f796898f Mon Sep 17 00:00:00 2001 From: Maick Speck Date: Fri, 17 Jun 2022 20:37:05 -0300 Subject: [PATCH 13/16] mock mongoose connection --- test/mock/mongoose/mock-mongoose.ts | 32 ++++++++++--------- .../custom-error-exception.filter.spec.ts | 3 +- .../transform-response.interceptor.spec.ts | 3 +- 3 files changed, 21 insertions(+), 17 deletions(-) diff --git a/test/mock/mongoose/mock-mongoose.ts b/test/mock/mongoose/mock-mongoose.ts index 74982ea..32fa375 100644 --- a/test/mock/mongoose/mock-mongoose.ts +++ b/test/mock/mongoose/mock-mongoose.ts @@ -13,18 +13,20 @@ export const mockModelMongoose = { } }; -jest.mock('mongoose', () => { - return { - createConnection: jest.fn(() => { - return { - asPromise: jest.fn(() => { - return { - model: jest.fn(), - close: jest.fn() - }; - }) - }; - }), - Schema: jest.fn() - }; -}); +export function mockMongooseConnection() { + jest.mock('mongoose', () => { + return { + createConnection: jest.fn(() => { + return { + asPromise: jest.fn(() => { + return { + model: jest.fn(), + close: jest.fn() + }; + }) + }; + }), + Schema: jest.fn() + }; + }); +} diff --git a/test/unit/core/error-handling/filter/custom-error-exception.filter.spec.ts b/test/unit/core/error-handling/filter/custom-error-exception.filter.spec.ts index e571d9f..3ab7f44 100644 --- a/test/unit/core/error-handling/filter/custom-error-exception.filter.spec.ts +++ b/test/unit/core/error-handling/filter/custom-error-exception.filter.spec.ts @@ -13,9 +13,10 @@ import { AppModule } from '../../../../../src/app.module'; import { Neighborhood } from '../../../../../src/microservice/domain/schemas/neighborhood.schema'; import { mockModelMongoose } from '../../../../mock/mongoose/mock-mongoose'; import { getModelToken } from '@nestjs/mongoose'; -import '../../../../mock/mongoose/mock-mongoose.ts'; +import { mockMongooseConnection } from '../../../../mock/mongoose/mock-mongoose'; jest.setTimeout(25000); +mockMongooseConnection(); describe('CustomErrorExceptionFilter', () => { let sut: CustomErrorExceptionFilter; diff --git a/test/unit/core/http/transform-response.interceptor.spec.ts b/test/unit/core/http/transform-response.interceptor.spec.ts index c443fa1..67742c5 100644 --- a/test/unit/core/http/transform-response.interceptor.spec.ts +++ b/test/unit/core/http/transform-response.interceptor.spec.ts @@ -16,9 +16,10 @@ import { CustomResponse } from '../../../../src/core/interface/custom-response.i import { of } from 'rxjs'; import * as sinon from 'sinon'; -import '../../../mock/mongoose/mock-mongoose.ts'; +import { mockMongooseConnection } from '../../../mock/mongoose/mock-mongoose'; jest.setTimeout(22000); +mockMongooseConnection(); describe('TransformResponseInterceptor ', () => { let app: INestApplication; From cc2912fbb51e81886a13f953c47ae27213d3f093 Mon Sep 17 00:00:00 2001 From: Maick Speck Date: Fri, 17 Jun 2022 20:53:27 -0300 Subject: [PATCH 14/16] jest mock verbose --- .../custom-error-exception.filter.spec.ts | 17 +++++++++++++++-- .../transform-response.interceptor.spec.ts | 18 +++++++++++++++--- 2 files changed, 30 insertions(+), 5 deletions(-) diff --git a/test/unit/core/error-handling/filter/custom-error-exception.filter.spec.ts b/test/unit/core/error-handling/filter/custom-error-exception.filter.spec.ts index 3ab7f44..836c8c7 100644 --- a/test/unit/core/error-handling/filter/custom-error-exception.filter.spec.ts +++ b/test/unit/core/error-handling/filter/custom-error-exception.filter.spec.ts @@ -13,10 +13,23 @@ import { AppModule } from '../../../../../src/app.module'; import { Neighborhood } from '../../../../../src/microservice/domain/schemas/neighborhood.schema'; import { mockModelMongoose } from '../../../../mock/mongoose/mock-mongoose'; import { getModelToken } from '@nestjs/mongoose'; -import { mockMongooseConnection } from '../../../../mock/mongoose/mock-mongoose'; jest.setTimeout(25000); -mockMongooseConnection(); +jest.mock('mongoose', () => { + return { + createConnection: jest.fn(() => { + return { + asPromise: jest.fn(() => { + return { + model: jest.fn(), + close: jest.fn() + }; + }) + }; + }), + Schema: jest.fn() + }; +}); describe('CustomErrorExceptionFilter', () => { let sut: CustomErrorExceptionFilter; diff --git a/test/unit/core/http/transform-response.interceptor.spec.ts b/test/unit/core/http/transform-response.interceptor.spec.ts index 67742c5..f2ab749 100644 --- a/test/unit/core/http/transform-response.interceptor.spec.ts +++ b/test/unit/core/http/transform-response.interceptor.spec.ts @@ -16,10 +16,22 @@ import { CustomResponse } from '../../../../src/core/interface/custom-response.i import { of } from 'rxjs'; import * as sinon from 'sinon'; -import { mockMongooseConnection } from '../../../mock/mongoose/mock-mongoose'; - jest.setTimeout(22000); -mockMongooseConnection(); +jest.mock('mongoose', () => { + return { + createConnection: jest.fn(() => { + return { + asPromise: jest.fn(() => { + return { + model: jest.fn(), + close: jest.fn() + }; + }) + }; + }), + Schema: jest.fn() + }; +}); describe('TransformResponseInterceptor ', () => { let app: INestApplication; From a43966bcffc30ff247a3069852490dd999161e65 Mon Sep 17 00:00:00 2001 From: Maick Speck Date: Sat, 18 Jun 2022 14:44:16 -0300 Subject: [PATCH 15/16] fix code smell mongo --- .../builder/neighborhoods-mongo.builder.ts | 2 +- .../builder/neighborhoods-puppeteer.builder.ts | 2 +- .../neighborhoods-mongoose.repository.ts | 2 +- test/mock/mongoose/mock-mongoose.ts | 18 ------------------ 4 files changed, 3 insertions(+), 21 deletions(-) diff --git a/src/microservice/adapter/helper/builder/neighborhoods-mongo.builder.ts b/src/microservice/adapter/helper/builder/neighborhoods-mongo.builder.ts index a3c0ffd..00dd645 100644 --- a/src/microservice/adapter/helper/builder/neighborhoods-mongo.builder.ts +++ b/src/microservice/adapter/helper/builder/neighborhoods-mongo.builder.ts @@ -3,7 +3,7 @@ import { NeighborhoodsByCity } from '../../../domain/model/neighborhoods-by-city import { Neighborhood } from '../../../domain/schemas/neighborhood.schema'; export class NeighborhoodsMongoBuilder { - constructor(private puppeteerResponse: NeighborhoodsByCity[]) {} + constructor(private readonly puppeteerResponse: NeighborhoodsByCity[]) {} build(searchParams: SearchNeighborhoods): Neighborhood[] { const arr = []; diff --git a/src/microservice/adapter/helper/builder/neighborhoods-puppeteer.builder.ts b/src/microservice/adapter/helper/builder/neighborhoods-puppeteer.builder.ts index 0496e82..2dd4d8e 100644 --- a/src/microservice/adapter/helper/builder/neighborhoods-puppeteer.builder.ts +++ b/src/microservice/adapter/helper/builder/neighborhoods-puppeteer.builder.ts @@ -2,7 +2,7 @@ import { NeighborhoodsByCity } from '../../../domain/model/neighborhoods-by-city import { Neighborhood } from '../../../domain/schemas/neighborhood.schema'; export class NeighborhoodsPuppeteerBuilder { - constructor(private mongoResponse: Neighborhood[]) {} + constructor(private readonly mongoResponse: Neighborhood[]) {} build(): NeighborhoodsByCity[] { const arr = []; diff --git a/src/microservice/adapter/repository/neighborhoods/neighborhoods-mongoose.repository.ts b/src/microservice/adapter/repository/neighborhoods/neighborhoods-mongoose.repository.ts index 7cfbad2..c1635a2 100644 --- a/src/microservice/adapter/repository/neighborhoods/neighborhoods-mongoose.repository.ts +++ b/src/microservice/adapter/repository/neighborhoods/neighborhoods-mongoose.repository.ts @@ -20,6 +20,6 @@ export class NeighborhoodsMongoose extends MongooseRepository { async findBySearchParams( searchParams: SearchNeighborhoods ): Promise { - return await this.model.find(searchParams).select({ _id: 0 }).lean().exec(); + return this.model.find(searchParams).select({ _id: 0 }).lean().exec(); } } diff --git a/test/mock/mongoose/mock-mongoose.ts b/test/mock/mongoose/mock-mongoose.ts index 32fa375..a66452e 100644 --- a/test/mock/mongoose/mock-mongoose.ts +++ b/test/mock/mongoose/mock-mongoose.ts @@ -12,21 +12,3 @@ export const mockModelMongoose = { return { exec: jest.fn(() => null) }; } }; - -export function mockMongooseConnection() { - jest.mock('mongoose', () => { - return { - createConnection: jest.fn(() => { - return { - asPromise: jest.fn(() => { - return { - model: jest.fn(), - close: jest.fn() - }; - }) - }; - }), - Schema: jest.fn() - }; - }); -} From 0a48d59e29ac7b9ef6e0236dcad637c84330f9f5 Mon Sep 17 00:00:00 2001 From: Maick Speck Date: Mon, 20 Jun 2022 08:44:40 -0300 Subject: [PATCH 16/16] disable e2e --- .github/workflows/e2e-tests.yml | 40 ++++++++--------- test/e2e/app.e2e-spec.ts | 77 ++++++++++++++++++++------------- 2 files changed, 68 insertions(+), 49 deletions(-) diff --git a/.github/workflows/e2e-tests.yml b/.github/workflows/e2e-tests.yml index 99e63a6..50d6d1f 100644 --- a/.github/workflows/e2e-tests.yml +++ b/.github/workflows/e2e-tests.yml @@ -1,21 +1,21 @@ -name: e2e -on: - push: - branches: - - main - - development -jobs: - e2eTests: - name: e2e-Tests - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@v2 - with: - fetch-depth: 0 # Shallow clones should be disabled for a better relevancy of analysis - - name: install - run: npm install - - name: e2e test - run: npm run test:e2e - env: - GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} # Needed to get PR information, if any +# name: e2e +# on: +# push: +# branches: +# - main +# - development +# jobs: +# e2eTests: +# name: e2e-Tests +# runs-on: ubuntu-latest +# steps: +# - uses: actions/checkout@v2 +# with: +# fetch-depth: 0 # Shallow clones should be disabled for a better relevancy of analysis +# - name: install +# run: npm install +# - name: e2e test +# run: npm run test:e2e +# env: +# GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} # Needed to get PR information, if any diff --git a/test/e2e/app.e2e-spec.ts b/test/e2e/app.e2e-spec.ts index 531e271..c0c1549 100644 --- a/test/e2e/app.e2e-spec.ts +++ b/test/e2e/app.e2e-spec.ts @@ -1,29 +1,48 @@ -import { INestApplication } from '@nestjs/common'; -import * as request from 'supertest'; -import { expect } from 'chai'; -import { AppModule } from '../../src/app.module'; -import { NestFactory } from '@nestjs/core'; - -jest.useFakeTimers(); -jest.setTimeout(50000); - -describe('AppController (e2e)', () => { - let app: INestApplication; - - beforeEach(async () => { - app = await NestFactory.create(AppModule); - app.init(); - }); - - afterEach(async () => { - await app.close(); - }); - - it('/neighborhoods/city/brasil/sc/orleans (GET)', async () => { - const actual = await request(app.getHttpServer()) - .get('/neighborhoods/city/brasil/sc/orleans') - .expect(200); - - expect(actual.body).to.be.an('array').that.is.not.empty; - }); -}); +// import { INestApplication } from '@nestjs/common'; +// import * as request from 'supertest'; +// import { expect } from 'chai'; +// import { AppModule } from '../../src/app.module'; +// import { Test } from '@nestjs/testing'; +// import { Connection } from 'mongoose'; +// import { getConnectionToken } from '@nestjs/mongoose'; + +// jest.useFakeTimers(); +// jest.setTimeout(25000); + +// describe('App (e2e)', () => { +// let app: INestApplication; +// let connection: Connection; + +// // const url = `mongodb://dev-seeder-root:hpYpxyjrKExNQviu@devseeder-shard-00-00.v6xtv.mongodb.net:27017,devseeder-shard-00-01.v6xtv.mongodb.net:27017,devseeder-shard-00-02.v6xtv.mongodb.net:27017/places?ssl=true&replicaSet=atlas-4xi3m3-shard-0&authSource=admin&retryWrites=true&w=majority`; + +// beforeAll(async () => { +// const module = await Test.createTestingModule({ +// imports: [AppModule] +// }).compile(); + +// connection = await module.get(getConnectionToken()); + +// app = await module.createNestApplication(); +// await app.init(); +// }); + +// afterEach(async () => { +// await app.close(); +// }); + +// afterAll(async () => { +// await connection.close(/*force:*/ true); // <-- important +// }); + +// it('1 = 1', async () => { +// expect(1).to.be.equal(1); +// }); + +// it('/neighborhoods/city/brasil/sc/orleans (GET)', async () => { +// const actual = await request(app.getHttpServer()) +// .get('/neighborhoods/city/brasil/sc/orleans') +// .expect(200); + +// expect(actual.body).to.be.an('array').that.is.not.empty; +// }); +// });