From 75783ec3e1c922a3c8bed91587013872541622d8 Mon Sep 17 00:00:00 2001 From: Dan Levy Date: Fri, 17 Dec 2021 19:09:10 -0700 Subject: [PATCH 1/7] docs: Added example code & comments on correct usage. --- .../typescript-jest-node-fetch/.gitignore | 126 ++++++++++++ examples/typescript-jest-node-fetch/README.md | 40 ++++ .../getRepo_3662565679/recording.har | 191 ++++++++++++++++++ .../getUser-org-name_95565551/recording.har | 191 ++++++++++++++++++ .../getUser_1648904580/recording.har | 191 ++++++++++++++++++ .../typescript-jest-node-fetch/jest.config.ts | 19 ++ .../typescript-jest-node-fetch/package.json | 49 +++++ .../src/github-api.test.ts | 32 +++ .../src/github-api.ts | 18 ++ .../src/utils/auto-setup-polly.ts | 51 +++++ .../typescript-jest-node-fetch/tsconfig.json | 26 +++ 11 files changed, 934 insertions(+) create mode 100644 examples/typescript-jest-node-fetch/.gitignore create mode 100644 examples/typescript-jest-node-fetch/README.md create mode 100644 examples/typescript-jest-node-fetch/__recordings__/getRepo_3662565679/recording.har create mode 100644 examples/typescript-jest-node-fetch/__recordings__/getUser-org-name_95565551/recording.har create mode 100644 examples/typescript-jest-node-fetch/__recordings__/getUser_1648904580/recording.har create mode 100644 examples/typescript-jest-node-fetch/jest.config.ts create mode 100644 examples/typescript-jest-node-fetch/package.json create mode 100644 examples/typescript-jest-node-fetch/src/github-api.test.ts create mode 100644 examples/typescript-jest-node-fetch/src/github-api.ts create mode 100644 examples/typescript-jest-node-fetch/src/utils/auto-setup-polly.ts create mode 100644 examples/typescript-jest-node-fetch/tsconfig.json diff --git a/examples/typescript-jest-node-fetch/.gitignore b/examples/typescript-jest-node-fetch/.gitignore new file mode 100644 index 00000000..320e8538 --- /dev/null +++ b/examples/typescript-jest-node-fetch/.gitignore @@ -0,0 +1,126 @@ +# Logs +logs +*.log +npm-debug.log* +yarn-debug.log* +yarn-error.log* +lerna-debug.log* +.pnpm-debug.log* + +# Diagnostic reports (https://nodejs.org/api/report.html) +report.[0-9]*.[0-9]*.[0-9]*.[0-9]*.json + +# Runtime data +pids +*.pid +*.seed +*.pid.lock + +# Directory for instrumented libs generated by jscoverage/JSCover +lib-cov + +# Coverage directory used by tools like istanbul +coverage +*.lcov + +# nyc test coverage +.nyc_output + +# Grunt intermediate storage (https://gruntjs.com/creating-plugins#storing-task-files) +.grunt + +# Bower dependency directory (https://bower.io/) +bower_components + +# node-waf configuration +.lock-wscript + +# Compiled binary addons (https://nodejs.org/api/addons.html) +build/Release + +# Dependency directories +node_modules +jspm_packages/ + +# Snowpack dependency directory (https://snowpack.dev/) +web_modules/ + +# TypeScript cache +*.tsbuildinfo + +# Optional npm cache directory +.npm + +# Optional eslint cache +.eslintcache + +# Optional stylelint cache +.stylelintcache + +# Microbundle cache +.rpt2_cache/ +.rts2_cache_cjs/ +.rts2_cache_es/ +.rts2_cache_umd/ + +# Optional REPL history +.node_repl_history + +# Output of 'npm pack' +*.tgz + +# Yarn Integrity file +.yarn-integrity + +# dotenv environment variables file +.env.development.local +.env.test.local +.env.production.local +.env.local + +# parcel-bundler cache (https://parceljs.org/) +.cache +.parcel-cache + +# Next.js build output +.next +out + +# Nuxt.js build / generate output +.nuxt +dist + +# Gatsby files +.cache/ +# Comment in the public line in if your project uses Gatsby and not Next.js +# https://nextjs.org/blog/next-9-1#public-directory-support +# public + +# vuepress build output +.vuepress/dist + +# vuepress v2.x temp and cache directory +.temp +.cache + +# Serverless directories +.serverless/ + +# FuseBox cache +.fusebox/ + +# DynamoDB Local files +.dynamodb/ + +# TernJS port file +.tern-port + +# Stores VSCode versions used for testing VSCode extensions +.vscode-test + +# yarn v2 +.yarn/cache +.yarn/unplugged +.yarn/build-state.yml +.yarn/install-state.gz +.pnp.* diff --git a/examples/typescript-jest-node-fetch/README.md b/examples/typescript-jest-node-fetch/README.md new file mode 100644 index 00000000..5808def9 --- /dev/null +++ b/examples/typescript-jest-node-fetch/README.md @@ -0,0 +1,40 @@ +# Notes + +## For Node.js users + +In Node.js environments Polly uses `nock` under the hood. + + + +### [**NOCK_BACK_MODE**](https://github.com/nock/nock#modes) + +- `lockdown` - use recorded nocks, **disables** all http calls even when not nocked, doesn't record. +- `wild` - all requests go out to the internet, don't replay anything, doesn't record anything. +- `record` - use recorded nocks, record new nocks. +- `update` - remove recorded nocks, record nocks. +- `dryrun` - *default* use recorded nocks, allow http calls, doesn't record anything, useful for writing new tests. + +Handy scripts for your `package.json`: + +```json +{ + "test": "yarn --coverage --watchAll", + "test:record": "NOCK_BACK_MODE=record yarn test", + "test:refresh": "NOCK_BACK_MODE=update yarn test", + "test:offline": "NOCK_BACK_MODE=lockdown yarn test", + "test:live": "NOCK_BACK_MODE=wild yarn test", +} + +``` + +### **DEBUG** Environment Variable + +- The `DEBUG` variable lets you see plenty of interesting internal details for many popular nodejs libraries. + +```json +{ + "test:log-minimal": "DEBUG=nock.scope yarn test", + "test:log-short": "DEBUG=nock.intercept yarn test", + "test:log-data": "DEBUG=nock.*intercept* yarn test" +} +``` diff --git a/examples/typescript-jest-node-fetch/__recordings__/getRepo_3662565679/recording.har b/examples/typescript-jest-node-fetch/__recordings__/getRepo_3662565679/recording.har new file mode 100644 index 00000000..2854ce09 --- /dev/null +++ b/examples/typescript-jest-node-fetch/__recordings__/getRepo_3662565679/recording.har @@ -0,0 +1,191 @@ +{ + "log": { + "_recordingName": "getRepo", + "creator": { + "comment": "persister:fs", + "name": "Polly.JS", + "version": "5.1.1" + }, + "entries": [ + { + "_id": "4b30564a4a0ffa8eb058c9db43ae9bbb", + "_order": 0, + "cache": {}, + "request": { + "bodySize": 0, + "cookies": [], + "headers": [ + { + "_fromType": "array", + "name": "accept", + "value": "application/json+vnd.github.v3.raw" + }, + { + "_fromType": "array", + "name": "content-type", + "value": "application/json" + }, + { + "_fromType": "array", + "name": "user-agent", + "value": "node-fetch/1.0 (+https://github.com/bitinn/node-fetch)" + }, + { + "_fromType": "array", + "name": "accept-encoding", + "value": "gzip,deflate" + }, + { + "_fromType": "array", + "name": "connection", + "value": "close" + }, + { + "name": "host", + "value": "api.github.com" + } + ], + "headersSize": 275, + "httpVersion": "HTTP/1.1", + "method": "GET", + "queryString": [], + "url": "https://api.github.com/repos/facebook/jest" + }, + "response": { + "bodySize": 1395, + "content": { + "_isBinary": true, + "mimeType": "application/json; charset=utf-8", + "size": 1395, + "text": "[\"1f8b0800000000000003ed58516fdb3610fe2b855ee758b613bb8981a01bd0ae68b134d866605d86c1a024daa24d890249d97184fcf77d24254b36dc26e6d31efa92d8f47d1f8f\",\"c7bbe3dd55014b82e9703c988cae2737bd2017099d9ba5e0eefd87ed3dffcce38f374fe4eb1f9b385f3f7e99fd32ba5b2d47f7bfdfde0610261985e48a2a8d6f8b92f379bdb420318d845887f56f85641ba221bc205cd15e20b63995c1b40ab858b21c1c0d003c66f7c9cde47278a4cdee7e7db37b18fd5a92af459a7ce49b68f5f7f8cbeaee1118027622e7a5e4e04ab52ed4340cdda2ea2f994ecba85454c622d734d7fd58646119da4dde6d6eaf40b09435853d3b168ea80a56d3382cb854d8d139d5193fdadded6ac53b820bc1b9d8027dacebf73608f7286366cbc0f2a50703505528744a612a1ce1d91c9c297d9e32165185e61f3cc57028d85ed2e42c856a0cd431aef05c859216c29295918a252b3413f9798a1d20c124e492e4ec899ccf04a4028151e93c152c0248ba819b9d0775902ab4a112ef8c29248d29dbc0b01e744758b0e95d61a2f5be6315636ea6e99c249989421b9ccf3d04d06bbcb989ed84eeef0bf4ef2967cb542319bcf98c90fad35ee59b1952049caf8f0d1742aef779e0bb51668db90f9e663b837fc1b227800821c0b0fd9aee3cd0065585f85b7b7c8c20249190448b9742f9943207f02aec7e35f7ae29c93c94b430c053245e0fb88501ce942ae9ab5ceed4d12c5a858d37e76516b944f31a1f3e45e870d08b28c59639a51e47db43abb0c97b9124799cfa9035c82a749fec8d91a5875a060570c445e481c603135a6815aa94b85caee77e9a182e833ca09274e1a99641eea9b4f4ba33ab9281ee89f064685c9f874e0d32ac6a4b71922f4bb2f4e1da437173e6115b92a7179ff3537edd6241640a13c9a2d2379db468a3957b4111773ea66ac12d957d8cbfffbc9f3c62e729b787cc32f6d2ab788aa7061e38a73799f1ab6342f3fde507fb5baa196415b699ce25d09af37cabd519b4d1a9cb5cd7af1ed7da20c3eaa782e8d4640b6c501049cf57b006865544502ef4fbfd2aa5c4168219955e31e5702020324e51f19caf53d520f1ce6744db7a7261544a505f7241120f9beda1a0719772be5e0ed7bdc3026d92873216d6e5c918475125729f1cd662bb8cb9d06cc1e2d7d4cba742e1005ebd532c8f698f70de8397691633f81d4a407327289da88f0d1c0e2aa3ef74f531a770410f6b4aea9055e83a9884165cec3c7340076cc24a5274bac99c6854c3a3c1f0f26238ba180e6683c174783d1d5c3d40a62c92aecc686865ae8dcc683c1d0d8d4c51aab4a5a945dece462323723530224865b547e2131ade132da7ad9a4deb0a71a5d256fce75618757fa75baf85630ed73af2f797f837c76fc4b700502615192df00277fa75a3ea4af59930bab227fc349a5c0ddf0e0eded95894392c7bf9f6f266dc0bb644a388c33b77b8dcbcd1209fa1eb714d88d994a8b98bc860aa658941845929a458d158abee5a1bfb1dc12d5bb303a0a9209a05d797d47a8cc7438c2f3226a5a8a71239e2779fdf3063a80721095324e2b45d1005cd6b1d9b430d27d7b0016731cd158c52991e0627c35b8a23d50397bb4fb337bfd512b057913cd6539c4f33e36f877391c359434dacc29ab033018a27b38f7cf5f0d7f8e961f6e129406b887816dbb9392b62b9393a53734db38277273c5a142c8671fe0910a23be8401f0b18d926177cebce7bf0f64a85ac8fe5155a46d74de24b41588e1c674ae4e6e3452b70a15d4f895f554e0a950a638e66f1df5eb0618a458c336d8c559411ce6936b67de0d45d50c7d818825933371eb577b1842e48c9f5dc15fbc6ee50cbee94157317255aac29da6777c5dda9c38f0957671af763c2f563c2652be5ffc1842ba77a8b44d06458970dba7d539bc79fff033b7d58e823170000\"]" + }, + "cookies": [], + "headers": [ + { + "name": "server", + "value": "GitHub.com" + }, + { + "name": "date", + "value": "Sat, 18 Dec 2021 02:14:48 GMT" + }, + { + "name": "content-type", + "value": "application/json; charset=utf-8" + }, + { + "name": "cache-control", + "value": "public, max-age=60, s-maxage=60" + }, + { + "name": "vary", + "value": "Accept, Accept-Encoding, Accept, X-Requested-With" + }, + { + "name": "etag", + "value": "W/\"1b592ee24555e150564a4fff4e572f8d7e8571077e5457f0568640aab4465684\"" + }, + { + "name": "last-modified", + "value": "Sat, 18 Dec 2021 00:25:21 GMT" + }, + { + "name": "x-github-media-type", + "value": "github.v3; format=vnd.github.v3.raw" + }, + { + "name": "access-control-expose-headers", + "value": "ETag, Link, Location, Retry-After, X-GitHub-OTP, X-RateLimit-Limit, X-RateLimit-Remaining, X-RateLimit-Used, X-RateLimit-Resource, X-RateLimit-Reset, X-OAuth-Scopes, X-Accepted-OAuth-Scopes, X-Poll-Interval, X-GitHub-Media-Type, X-GitHub-SSO, X-GitHub-Request-Id, Deprecation, Sunset" + }, + { + "name": "access-control-allow-origin", + "value": "*" + }, + { + "name": "strict-transport-security", + "value": "max-age=31536000; includeSubdomains; preload" + }, + { + "name": "x-frame-options", + "value": "deny" + }, + { + "name": "x-content-type-options", + "value": "nosniff" + }, + { + "name": "x-xss-protection", + "value": "0" + }, + { + "name": "referrer-policy", + "value": "origin-when-cross-origin, strict-origin-when-cross-origin" + }, + { + "name": "content-security-policy", + "value": "default-src 'none'" + }, + { + "name": "content-encoding", + "value": "gzip" + }, + { + "name": "x-ratelimit-limit", + "value": "60" + }, + { + "name": "x-ratelimit-remaining", + "value": "50" + }, + { + "name": "x-ratelimit-reset", + "value": "1639796310" + }, + { + "name": "x-ratelimit-resource", + "value": "core" + }, + { + "name": "x-ratelimit-used", + "value": "10" + }, + { + "name": "accept-ranges", + "value": "bytes" + }, + { + "name": "content-length", + "value": "1395" + }, + { + "name": "x-github-request-id", + "value": "EEAE:63BE:99865:2DAECA:61BD4418" + }, + { + "name": "connection", + "value": "close" + } + ], + "headersSize": 1282, + "httpVersion": "HTTP/1.1", + "redirectURL": "", + "status": 200, + "statusText": "OK" + }, + "startedDateTime": "2021-12-18T02:14:47.816Z", + "time": 273, + "timings": { + "blocked": -1, + "connect": -1, + "dns": -1, + "receive": 0, + "send": 0, + "ssl": -1, + "wait": 273 + } + } + ], + "pages": [], + "version": "1.2" + } +} diff --git a/examples/typescript-jest-node-fetch/__recordings__/getUser-org-name_95565551/recording.har b/examples/typescript-jest-node-fetch/__recordings__/getUser-org-name_95565551/recording.har new file mode 100644 index 00000000..7bd27226 --- /dev/null +++ b/examples/typescript-jest-node-fetch/__recordings__/getUser-org-name_95565551/recording.har @@ -0,0 +1,191 @@ +{ + "log": { + "_recordingName": "getUser: org name", + "creator": { + "comment": "persister:fs", + "name": "Polly.JS", + "version": "5.1.1" + }, + "entries": [ + { + "_id": "87a2a6f326da043bea5bb7614c378003", + "_order": 0, + "cache": {}, + "request": { + "bodySize": 0, + "cookies": [], + "headers": [ + { + "_fromType": "array", + "name": "accept", + "value": "application/json+vnd.github.v3.raw" + }, + { + "_fromType": "array", + "name": "content-type", + "value": "application/json" + }, + { + "_fromType": "array", + "name": "user-agent", + "value": "node-fetch/1.0 (+https://github.com/bitinn/node-fetch)" + }, + { + "_fromType": "array", + "name": "accept-encoding", + "value": "gzip,deflate" + }, + { + "_fromType": "array", + "name": "connection", + "value": "close" + }, + { + "name": "host", + "value": "api.github.com" + } + ], + "headersSize": 270, + "httpVersion": "HTTP/1.1", + "method": "GET", + "queryString": [], + "url": "https://api.github.com/users/facebook" + }, + "response": { + "bodySize": 566, + "content": { + "_isBinary": true, + "mimeType": "application/json; charset=utf-8", + "size": 566, + "text": "[\"1f8b08000000000000039d53db8adb3010fd15a1e724be64b3ec0a4aa1d7a76c0a5de8362f41b6155b1b5963e4915337ecbf776487ad9b8742160cb6c59ccb8ce69cb881525b2e\",\"f85ee62a0338f019d70517b7f7b7cb64c62d146a17fef9fad3e77e73b8efb7e9172f9f9aaaf86abaecf9e7eae179fd8b30b29328ddce3b43b51562d38a281a0fdb45a9b1f2996f95cbc1a2b2b8c8a18e7c3488bcefdedd1041e9ce14831a1d5c5035fa4c336289ab8d269e2baccd85faa83a944f0af7600c1c097de9f57f02d12b8a8c8ddfda966f6020d42902ac148d8a5a78098deb16af3333204e5178d1dd048e9666ef547195a13386ec1c2d3939454e353090f9accd9d6e5083bdced83f486202574aab7fcbeb9908d91241b0749d85014148d5d19a5d071d21a7a871ba93791f46e154ae7447837d03dd0596d8b06f14edf6663295306e8d6a278b3aa4702f4dab2875b20e856b85920a68811b697b2eac3766c6334aec2463d028db8277b95aecb3b0ec8430900f331f38ac01f64dbac38c7d9446efc1591d58552d356575e4acb4533233247ad6d040d81f8a49a7d811dc81f69621b0cc6b533012a9bdd5d833ac1cf8b262c1041b5d30547965814cf60bf6f041b05ad519c58dd5be4556c94e313cc29c1289e098f4582dc2688e1af11c8a49f71be2fd3e3447358dcf8cce77e30d8b24495f8f864070114efe0655c493a8f2f0975393489729919a4be3f87e1edfcce3f4315e8ae54aa4e996447c534c6bd2649ed0133f2677627927e2d596bffc0129c9ebed34050000\"]" + }, + "cookies": [], + "headers": [ + { + "name": "server", + "value": "GitHub.com" + }, + { + "name": "date", + "value": "Sat, 18 Dec 2021 02:14:47 GMT" + }, + { + "name": "content-type", + "value": "application/json; charset=utf-8" + }, + { + "name": "cache-control", + "value": "public, max-age=60, s-maxage=60" + }, + { + "name": "vary", + "value": "Accept, Accept-Encoding, Accept, X-Requested-With" + }, + { + "name": "etag", + "value": "W/\"76fcb794577ec048f99f9d8f0d2cad3180c61288665ea43b7623b80c1dffd6ff\"" + }, + { + "name": "last-modified", + "value": "Wed, 10 Nov 2021 18:38:05 GMT" + }, + { + "name": "x-github-media-type", + "value": "github.v3; format=vnd.github.v3.raw" + }, + { + "name": "access-control-expose-headers", + "value": "ETag, Link, Location, Retry-After, X-GitHub-OTP, X-RateLimit-Limit, X-RateLimit-Remaining, X-RateLimit-Used, X-RateLimit-Resource, X-RateLimit-Reset, X-OAuth-Scopes, X-Accepted-OAuth-Scopes, X-Poll-Interval, X-GitHub-Media-Type, X-GitHub-SSO, X-GitHub-Request-Id, Deprecation, Sunset" + }, + { + "name": "access-control-allow-origin", + "value": "*" + }, + { + "name": "strict-transport-security", + "value": "max-age=31536000; includeSubdomains; preload" + }, + { + "name": "x-frame-options", + "value": "deny" + }, + { + "name": "x-content-type-options", + "value": "nosniff" + }, + { + "name": "x-xss-protection", + "value": "0" + }, + { + "name": "referrer-policy", + "value": "origin-when-cross-origin, strict-origin-when-cross-origin" + }, + { + "name": "content-security-policy", + "value": "default-src 'none'" + }, + { + "name": "content-encoding", + "value": "gzip" + }, + { + "name": "x-ratelimit-limit", + "value": "60" + }, + { + "name": "x-ratelimit-remaining", + "value": "51" + }, + { + "name": "x-ratelimit-reset", + "value": "1639796309" + }, + { + "name": "x-ratelimit-resource", + "value": "core" + }, + { + "name": "x-ratelimit-used", + "value": "9" + }, + { + "name": "accept-ranges", + "value": "bytes" + }, + { + "name": "content-length", + "value": "566" + }, + { + "name": "x-github-request-id", + "value": "EEAD:72E7:C2A4BD:146FA37:61BD4417" + }, + { + "name": "connection", + "value": "close" + } + ], + "headersSize": 1282, + "httpVersion": "HTTP/1.1", + "redirectURL": "", + "status": 200, + "statusText": "OK" + }, + "startedDateTime": "2021-12-18T02:14:47.562Z", + "time": 231, + "timings": { + "blocked": -1, + "connect": -1, + "dns": -1, + "receive": 0, + "send": 0, + "ssl": -1, + "wait": 231 + } + } + ], + "pages": [], + "version": "1.2" + } +} diff --git a/examples/typescript-jest-node-fetch/__recordings__/getUser_1648904580/recording.har b/examples/typescript-jest-node-fetch/__recordings__/getUser_1648904580/recording.har new file mode 100644 index 00000000..fc96d720 --- /dev/null +++ b/examples/typescript-jest-node-fetch/__recordings__/getUser_1648904580/recording.har @@ -0,0 +1,191 @@ +{ + "log": { + "_recordingName": "getUser", + "creator": { + "comment": "persister:fs", + "name": "Polly.JS", + "version": "5.1.1" + }, + "entries": [ + { + "_id": "daab17694c1a59a0f3781977d2bf32d7", + "_order": 0, + "cache": {}, + "request": { + "bodySize": 0, + "cookies": [], + "headers": [ + { + "_fromType": "array", + "name": "accept", + "value": "application/json+vnd.github.v3.raw" + }, + { + "_fromType": "array", + "name": "content-type", + "value": "application/json" + }, + { + "_fromType": "array", + "name": "user-agent", + "value": "node-fetch/1.0 (+https://github.com/bitinn/node-fetch)" + }, + { + "_fromType": "array", + "name": "accept-encoding", + "value": "gzip,deflate" + }, + { + "_fromType": "array", + "name": "connection", + "value": "close" + }, + { + "name": "host", + "value": "api.github.com" + } + ], + "headersSize": 269, + "httpVersion": "HTTP/1.1", + "method": "GET", + "queryString": [], + "url": "https://api.github.com/users/netflix" + }, + "response": { + "bodySize": 525, + "content": { + "_isBinary": true, + "mimeType": "application/json; charset=utf-8", + "size": 525, + "text": "[\"1f8b080000000000000395935f6f9b3014c5bf0af2338981aceb8a146dd2fe5493d666d25aa9ca4b64c081bb1adbb20d2945fdeebb06b2647998c41360dddfb987eb7b7a22\",\"540992a4e49ebbbd8017121228487a13afaede5f8744aa82effc01b9fbf2b5db3cdf74dbe45bc39e7455dc8a36fbfdfc72f7fa98dc1fd66b0459cb1c33bbc608acaf9cd336a5743cb4cb125cd5648de52657d271e996b9aa6943c74e1fdbf53b5428cda431b4c4830b2d0d93ce08a398a527e395abc545f7b1eb507daadb2b21d401d94babff91a77f217435be832ce70b20d453e52a8e7342fb6ffea7c1ba595606a0a7fe8177e3252cceddf0628e9d09413307893e7a6ab856835693d9dc8076a0e42c5bff8028a44cc924bcb2d942085ae4bda15906060041dee27acd2247a2a7da40cbf2ce8fc1f09c438b339daf7681a298eb34c785de9c4dc44f1a1cdfb1a2f6f9db336139e68dd5be70dad530f82ef32556e2fe6a263b92ca4688906418da296298303926f7980c501409a1f261f058f643d9e0963965c3e03313b0574602f363aa19f8a44ebcb2f6d3510afb61410586b34ca0a1a92da893b760a3b90c7ea9c6e43cf82998435d0fb90338376df7f83723ac9b4c40be1bef284da20f21998e8675266974cc1506f3ec0b03337ce5e8c5e17530871e92288e17d1f5225e3d24118aa551bcc5de8d2ece6b926811278b287948927415a7abab2d79fb03b458ebc7f1040000\"]" + }, + "cookies": [], + "headers": [ + { + "name": "server", + "value": "GitHub.com" + }, + { + "name": "date", + "value": "Sat, 18 Dec 2021 02:51:42 GMT" + }, + { + "name": "content-type", + "value": "application/json; charset=utf-8" + }, + { + "name": "cache-control", + "value": "public, max-age=60, s-maxage=60" + }, + { + "name": "vary", + "value": "Accept, Accept-Encoding, Accept, X-Requested-With" + }, + { + "name": "etag", + "value": "W/\"e7c5ada389fe724c41d8b2248ede8e368c0fdd159f907ca79d9c0a78fa3344cb\"" + }, + { + "name": "last-modified", + "value": "Wed, 02 Dec 2020 22:31:35 GMT" + }, + { + "name": "x-github-media-type", + "value": "github.v3; format=vnd.github.v3.raw" + }, + { + "name": "access-control-expose-headers", + "value": "ETag, Link, Location, Retry-After, X-GitHub-OTP, X-RateLimit-Limit, X-RateLimit-Remaining, X-RateLimit-Used, X-RateLimit-Resource, X-RateLimit-Reset, X-OAuth-Scopes, X-Accepted-OAuth-Scopes, X-Poll-Interval, X-GitHub-Media-Type, X-GitHub-SSO, X-GitHub-Request-Id, Deprecation, Sunset" + }, + { + "name": "access-control-allow-origin", + "value": "*" + }, + { + "name": "strict-transport-security", + "value": "max-age=31536000; includeSubdomains; preload" + }, + { + "name": "x-frame-options", + "value": "deny" + }, + { + "name": "x-content-type-options", + "value": "nosniff" + }, + { + "name": "x-xss-protection", + "value": "0" + }, + { + "name": "referrer-policy", + "value": "origin-when-cross-origin, strict-origin-when-cross-origin" + }, + { + "name": "content-security-policy", + "value": "default-src 'none'" + }, + { + "name": "content-encoding", + "value": "gzip" + }, + { + "name": "x-ratelimit-limit", + "value": "60" + }, + { + "name": "x-ratelimit-remaining", + "value": "49" + }, + { + "name": "x-ratelimit-reset", + "value": "1639796310" + }, + { + "name": "x-ratelimit-resource", + "value": "core" + }, + { + "name": "x-ratelimit-used", + "value": "11" + }, + { + "name": "accept-ranges", + "value": "bytes" + }, + { + "name": "content-length", + "value": "525" + }, + { + "name": "x-github-request-id", + "value": "F0FE:59E5:11836D1:2EFAA44:61BD4CBE" + }, + { + "name": "connection", + "value": "close" + } + ], + "headersSize": 1284, + "httpVersion": "HTTP/1.1", + "redirectURL": "", + "status": 200, + "statusText": "OK" + }, + "startedDateTime": "2021-12-18T02:51:41.766Z", + "time": 288, + "timings": { + "blocked": -1, + "connect": -1, + "dns": -1, + "receive": 0, + "send": 0, + "ssl": -1, + "wait": 288 + } + } + ], + "pages": [], + "version": "1.2" + } +} diff --git a/examples/typescript-jest-node-fetch/jest.config.ts b/examples/typescript-jest-node-fetch/jest.config.ts new file mode 100644 index 00000000..0501c168 --- /dev/null +++ b/examples/typescript-jest-node-fetch/jest.config.ts @@ -0,0 +1,19 @@ +import type { Config } from "@jest/types"; + +// Sync object +const config: Config.InitialOptions = { + rootDir: ".", + preset: "ts-jest", + testEnvironment: "setup-polly-jest/jest-environment-jsdom", + verbose: true, + testPathIgnorePatterns: ["node_modules", "dist"], + resetModules: true, + globals: { + "ts-jest": { + useESM: true, + }, + }, + transform: { }, +}; + +export default config; diff --git a/examples/typescript-jest-node-fetch/package.json b/examples/typescript-jest-node-fetch/package.json new file mode 100644 index 00000000..8911860c --- /dev/null +++ b/examples/typescript-jest-node-fetch/package.json @@ -0,0 +1,49 @@ +{ + "name": "typescript-jest-node-fetch", + "version": "1.0.0", + "private": true, + "main": "index.js", + "type": "commonjs", + "exports": "./dist/index.js", + "scripts": { + "test": "jest --runInBand", + "test:record": "POLLY_MODE=record jest --runInBand --verbose" + }, + "keywords": [ + "pollyjs", + "test-mocking", + "jest", + "node", + "typescript", + "fetch" + ], + "author": "", + "license": "Apache-2.0", + "dependencies": { + "node-fetch": "^2.6.6" + }, + "devDependencies": { + "@pollyjs/adapter-fetch": "^5.1.1", + "@pollyjs/adapter-node-http": "^5.1.1", + "@pollyjs/core": "^5.1.1", + "@pollyjs/node-server": "^5.1.1", + "@pollyjs/persister-fs": "^5.1.1", + "@types/jest": "^26.0.0", + "@types/node": "^16.11.11", + "@types/node-fetch": "^2.5.12", + "@types/pollyjs__adapter": "^4.3.1", + "@types/pollyjs__adapter-fetch": "^2.0.1", + "@types/pollyjs__adapter-node-http": "^2.0.1", + "@types/pollyjs__core": "^4.3.3", + "@types/pollyjs__persister": "^4.3.1", + "@types/pollyjs__persister-fs": "^2.0.1", + "@types/pollyjs__utils": "^2.6.1", + "@types/setup-polly-jest": "^0.5.1", + "jest": "^26.6.0", + "nodemon": "^2.0.15", + "setup-polly-jest": "^0.10.0", + "ts-jest": "^26.5.6", + "ts-node": "^10.4.0", + "typescript": "^4.5.2" + } +} diff --git a/examples/typescript-jest-node-fetch/src/github-api.test.ts b/examples/typescript-jest-node-fetch/src/github-api.test.ts new file mode 100644 index 00000000..65641625 --- /dev/null +++ b/examples/typescript-jest-node-fetch/src/github-api.test.ts @@ -0,0 +1,32 @@ +/** @jest-environment setup-polly-jest/jest-environment-node */ +import autoSetupPolly from "./utils/auto-setup-polly"; +import { getUser } from "./github-api"; + +// 🟡 Important: Run `autoSetupPolly()`/`setupPolly()` EARLY! +let pollyContext = autoSetupPolly(); +/* Polly/Nock MUST patch HTTP modules before your code `import`'s or `require`'s those modules. +✅ Place after `import`'s, OR at the top of first `describe()`. +❌ Do NOT setup in `beforeAll`/`beforeEach`! +*/ + +// beforeEach(() => { +// // Common or shared interceptors go here. +// pollyContext.polly.server +// .get("/ping") +// .intercept((req, res) => void res.sendStatus(200)); +// }); + +test("getUser", async () => { + const user: any = await getUser("netflix"); + expect(typeof user).toBe("object"); + expect(user?.login).toBe("Netflix"); +}); + +test("getUser: custom interceptor", async () => { + expect.assertions(1); + pollyContext.polly.server + .get("https://api.github.com/users/failing_request_trigger") + .intercept((req, res) => void res.sendStatus(500)); + + await expect(getUser("failing_request_trigger")).rejects.toThrow('Http Error: 500'); +}); diff --git a/examples/typescript-jest-node-fetch/src/github-api.ts b/examples/typescript-jest-node-fetch/src/github-api.ts new file mode 100644 index 00000000..33d10384 --- /dev/null +++ b/examples/typescript-jest-node-fetch/src/github-api.ts @@ -0,0 +1,18 @@ +import fetch from "node-fetch"; +import type { Response } from "node-fetch"; + +export const getUser = async (username: string): Promise => { + return fetch(`https://api.github.com/users/${username}`, { + headers: { + "Accept": "application/json+vnd.github.v3.raw", + "Content-type": "application/json", + }, + }) + .then(checkErrorAndReturnJson); +}; + +function checkErrorAndReturnJson(response: Response) { + return response.ok + ? response.json() + : Promise.reject(new Error(`Http Error: ${response.status}`)); +} diff --git a/examples/typescript-jest-node-fetch/src/utils/auto-setup-polly.ts b/examples/typescript-jest-node-fetch/src/utils/auto-setup-polly.ts new file mode 100644 index 00000000..9a64a7e7 --- /dev/null +++ b/examples/typescript-jest-node-fetch/src/utils/auto-setup-polly.ts @@ -0,0 +1,51 @@ +import path from "path"; +import { setupPolly } from "setup-polly-jest"; +import { Polly } from "@pollyjs/core"; +import NodeHttpAdapter from "@pollyjs/adapter-node-http"; +import FSPersister from "@pollyjs/persister-fs"; +// import FetchAdapter from "@pollyjs/adapter-fetch"; +// Polly.register(FetchAdapter); +Polly.register(NodeHttpAdapter); +Polly.register(FSPersister); + +const {POLLY_MODE} = process.env; + +let recordIfMissing = true; +if (POLLY_MODE === "offline") recordIfMissing = false; + +const pollyMode = POLLY_MODE === "record" ? "record" + : POLLY_MODE === "offline" ? "replay" + : "replay"; // Default is "replay" + +export default function autoSetupPolly() { + /** + * NOTE: Customize your config here, usually differs per project. + * + * This persister can be adapted for both Node.js and Browser environments. + */ + return setupPolly({ + // 🟡 Note: In node, all `fetch` like libraries use the http/https modules under the hood. + // `node-fetch` is handled by the `NodeHttpAdapter`, NOT the `FetchAdapter`. + adapters: ["node-http"], + mode: pollyMode, + recordIfMissing, + recordFailedRequests: true, + flushRequestsOnStop: true, + logging: false, + persister: "fs", + persisterOptions: { + fs: { + recordingsDir: path.resolve(__dirname, "../../__recordings__"), + }, + }, + }); +} + +/* +If you have trouble initializing/loading the interceptors early enough, try a singleton pattern for this module: + +1. Remove the `export default` here: `export default function autoSetupPolly() {:` +2. Add a new line: `export default autoSetupPolly();` + +Then when you `import` this module it will execute roughly immediately, and the default export will be the Context. +*/ \ No newline at end of file diff --git a/examples/typescript-jest-node-fetch/tsconfig.json b/examples/typescript-jest-node-fetch/tsconfig.json new file mode 100644 index 00000000..49004663 --- /dev/null +++ b/examples/typescript-jest-node-fetch/tsconfig.json @@ -0,0 +1,26 @@ +{ + "compilerOptions": { + "target": "ES5", + "lib": ["esnext"], + // "extendedDiagnostics": true, + "allowJs": true, + "skipLibCheck": true, + "esModuleInterop": true, + "allowSyntheticDefaultImports": true, + "strict": true, + "alwaysStrict": true, + "forceConsistentCasingInFileNames": true, + "noFallthroughCasesInSwitch": true, + "module": "ESNext", + "moduleResolution": "node", + "resolveJsonModule": true, + "isolatedModules": true, + // "noEmit": true, + "sourceMap": true, + "baseUrl": ".", + "rootDir": ".", + "outDir": "dist", + "useUnknownInCatchVariables": false + }, + "include": ["src"] +} From 62cb76ce3863ae6e64d24eb9b7507d4749e44efe Mon Sep 17 00:00:00 2001 From: Dan Levy Date: Fri, 17 Dec 2021 20:31:31 -0700 Subject: [PATCH 2/7] docs: Remove incomplete notes. --- examples/typescript-jest-node-fetch/README.md | 40 ---- .../getRepo_3662565679/recording.har | 191 ------------------ .../getUser-org-name_95565551/recording.har | 191 ------------------ .../getUser_1648904580/recording.har | 191 ------------------ .../typescript-jest-node-fetch/jest.config.ts | 1 - .../typescript-jest-node-fetch/package.json | 2 +- .../src/github-api.test.ts | 6 +- .../src/utils/auto-setup-polly.ts | 6 +- 8 files changed, 7 insertions(+), 621 deletions(-) delete mode 100644 examples/typescript-jest-node-fetch/README.md delete mode 100644 examples/typescript-jest-node-fetch/__recordings__/getRepo_3662565679/recording.har delete mode 100644 examples/typescript-jest-node-fetch/__recordings__/getUser-org-name_95565551/recording.har delete mode 100644 examples/typescript-jest-node-fetch/__recordings__/getUser_1648904580/recording.har diff --git a/examples/typescript-jest-node-fetch/README.md b/examples/typescript-jest-node-fetch/README.md deleted file mode 100644 index 5808def9..00000000 --- a/examples/typescript-jest-node-fetch/README.md +++ /dev/null @@ -1,40 +0,0 @@ -# Notes - -## For Node.js users - -In Node.js environments Polly uses `nock` under the hood. - - - -### [**NOCK_BACK_MODE**](https://github.com/nock/nock#modes) - -- `lockdown` - use recorded nocks, **disables** all http calls even when not nocked, doesn't record. -- `wild` - all requests go out to the internet, don't replay anything, doesn't record anything. -- `record` - use recorded nocks, record new nocks. -- `update` - remove recorded nocks, record nocks. -- `dryrun` - *default* use recorded nocks, allow http calls, doesn't record anything, useful for writing new tests. - -Handy scripts for your `package.json`: - -```json -{ - "test": "yarn --coverage --watchAll", - "test:record": "NOCK_BACK_MODE=record yarn test", - "test:refresh": "NOCK_BACK_MODE=update yarn test", - "test:offline": "NOCK_BACK_MODE=lockdown yarn test", - "test:live": "NOCK_BACK_MODE=wild yarn test", -} - -``` - -### **DEBUG** Environment Variable - -- The `DEBUG` variable lets you see plenty of interesting internal details for many popular nodejs libraries. - -```json -{ - "test:log-minimal": "DEBUG=nock.scope yarn test", - "test:log-short": "DEBUG=nock.intercept yarn test", - "test:log-data": "DEBUG=nock.*intercept* yarn test" -} -``` diff --git a/examples/typescript-jest-node-fetch/__recordings__/getRepo_3662565679/recording.har b/examples/typescript-jest-node-fetch/__recordings__/getRepo_3662565679/recording.har deleted file mode 100644 index 2854ce09..00000000 --- a/examples/typescript-jest-node-fetch/__recordings__/getRepo_3662565679/recording.har +++ /dev/null @@ -1,191 +0,0 @@ -{ - "log": { - "_recordingName": "getRepo", - "creator": { - "comment": "persister:fs", - "name": "Polly.JS", - "version": "5.1.1" - }, - "entries": [ - { - "_id": "4b30564a4a0ffa8eb058c9db43ae9bbb", - "_order": 0, - "cache": {}, - "request": { - "bodySize": 0, - "cookies": [], - "headers": [ - { - "_fromType": "array", - "name": "accept", - "value": "application/json+vnd.github.v3.raw" - }, - { - "_fromType": "array", - "name": "content-type", - "value": "application/json" - }, - { - "_fromType": "array", - "name": "user-agent", - "value": "node-fetch/1.0 (+https://github.com/bitinn/node-fetch)" - }, - { - "_fromType": "array", - "name": "accept-encoding", - "value": "gzip,deflate" - }, - { - "_fromType": "array", - "name": "connection", - "value": "close" - }, - { - "name": "host", - "value": "api.github.com" - } - ], - "headersSize": 275, - "httpVersion": "HTTP/1.1", - "method": "GET", - "queryString": [], - "url": "https://api.github.com/repos/facebook/jest" - }, - "response": { - "bodySize": 1395, - "content": { - "_isBinary": true, - "mimeType": "application/json; charset=utf-8", - "size": 1395, - "text": "[\"1f8b0800000000000003ed58516fdb3610fe2b855ee758b613bb8981a01bd0ae68b134d866605d86c1a024daa24d890249d97184fcf77d24254b36dc26e6d31efa92d8f47d1f8f\",\"c7bbe3dd55014b82e9703c988cae2737bd2017099d9ba5e0eefd87ed3dffcce38f374fe4eb1f9b385f3f7e99fd32ba5b2d47f7bfdfde0610261985e48a2a8d6f8b92f379bdb420318d845887f56f85641ba221bc205cd15e20b63995c1b40ab858b21c1c0d003c66f7c9cde47278a4cdee7e7db37b18fd5a92af459a7ce49b68f5f7f8cbeaee1118027622e7a5e4e04ab52ed4340cdda2ea2f994ecba85454c622d734d7fd58646119da4dde6d6eaf40b09435853d3b168ea80a56d3382cb854d8d139d5193fdadded6ac53b820bc1b9d8027dacebf73608f7286366cbc0f2a50703505528744a612a1ce1d91c9c297d9e32165185e61f3cc57028d85ed2e42c856a0cd431aef05c859216c29295918a252b3413f9798a1d20c124e492e4ec899ccf04a4028151e93c152c0248ba819b9d0775902ab4a112ef8c29248d29dbc0b01e744758b0e95d61a2f5be6315636ea6e99c249989421b9ccf3d04d06bbcb989ed84eeef0bf4ef2967cb542319bcf98c90fad35ee59b1952049caf8f0d1742aef779e0bb51668db90f9e663b837fc1b227800821c0b0fd9aee3cd0065585f85b7b7c8c20249190448b9742f9943207f02aec7e35f7ae29c93c94b430c053245e0fb88501ce942ae9ab5ceed4d12c5a858d37e76516b944f31a1f3e45e870d08b28c59639a51e47db43abb0c97b9124799cfa9035c82a749fec8d91a5875a060570c445e481c603135a6815aa94b85caee77e9a182e833ca09274e1a99641eea9b4f4ba33ab9281ee89f064685c9f874e0d32ac6a4b71922f4bb2f4e1da437173e6115b92a7179ff3537edd6241640a13c9a2d2379db468a3957b4111773ea66ac12d957d8cbfffbc9f3c62e729b787cc32f6d2ab788aa7061e38a73799f1ab6342f3fde507fb5baa196415b699ce25d09af37cabd519b4d1a9cb5cd7af1ed7da20c3eaa782e8d4640b6c501049cf57b006865544502ef4fbfd2aa5c4168219955e31e5702020324e51f19caf53d520f1ce6744db7a7261544a505f7241120f9beda1a0719772be5e0ed7bdc3026d92873216d6e5c918475125729f1cd662bb8cb9d06cc1e2d7d4cba742e1005ebd532c8f698f70de8397691633f81d4a407327289da88f0d1c0e2aa3ef74f531a770410f6b4aea9055e83a9884165cec3c7340076cc24a5274bac99c6854c3a3c1f0f26238ba180e6683c174783d1d5c3d40a62c92aecc686865ae8dcc683c1d0d8d4c51aab4a5a945dece462323723530224865b547e2131ade132da7ad9a4deb0a71a5d256fce75618757fa75baf85630ed73af2f797f837c76fc4b700502615192df00277fa75a3ea4af59930bab227fc349a5c0ddf0e0eded95894392c7bf9f6f266dc0bb644a388c33b77b8dcbcd1209fa1eb714d88d994a8b98bc860aa658941845929a458d158abee5a1bfb1dc12d5bb303a0a9209a05d797d47a8cc7438c2f3226a5a8a71239e2779fdf3063a80721095324e2b45d1005cd6b1d9b430d27d7b0016731cd158c52991e0627c35b8a23d50397bb4fb337bfd512b057913cd6539c4f33e36f877391c359434dacc29ab033018a27b38f7cf5f0d7f8e961f6e129406b887816dbb9392b62b9393a53734db38277273c5a142c8671fe0910a23be8401f0b18d926177cebce7bf0f64a85ac8fe5155a46d74de24b41588e1c674ae4e6e3452b70a15d4f895f554e0a950a638e66f1df5eb0618a458c336d8c559411ce6936b67de0d45d50c7d818825933371eb577b1842e48c9f5dc15fbc6ee50cbee94157317255aac29da6777c5dda9c38f0957671af763c2f563c2652be5ffc1842ba77a8b44d06458970dba7d539bc79fff033b7d58e823170000\"]" - }, - "cookies": [], - "headers": [ - { - "name": "server", - "value": "GitHub.com" - }, - { - "name": "date", - "value": "Sat, 18 Dec 2021 02:14:48 GMT" - }, - { - "name": "content-type", - "value": "application/json; charset=utf-8" - }, - { - "name": "cache-control", - "value": "public, max-age=60, s-maxage=60" - }, - { - "name": "vary", - "value": "Accept, Accept-Encoding, Accept, X-Requested-With" - }, - { - "name": "etag", - "value": "W/\"1b592ee24555e150564a4fff4e572f8d7e8571077e5457f0568640aab4465684\"" - }, - { - "name": "last-modified", - "value": "Sat, 18 Dec 2021 00:25:21 GMT" - }, - { - "name": "x-github-media-type", - "value": "github.v3; format=vnd.github.v3.raw" - }, - { - "name": "access-control-expose-headers", - "value": "ETag, Link, Location, Retry-After, X-GitHub-OTP, X-RateLimit-Limit, X-RateLimit-Remaining, X-RateLimit-Used, X-RateLimit-Resource, X-RateLimit-Reset, X-OAuth-Scopes, X-Accepted-OAuth-Scopes, X-Poll-Interval, X-GitHub-Media-Type, X-GitHub-SSO, X-GitHub-Request-Id, Deprecation, Sunset" - }, - { - "name": "access-control-allow-origin", - "value": "*" - }, - { - "name": "strict-transport-security", - "value": "max-age=31536000; includeSubdomains; preload" - }, - { - "name": "x-frame-options", - "value": "deny" - }, - { - "name": "x-content-type-options", - "value": "nosniff" - }, - { - "name": "x-xss-protection", - "value": "0" - }, - { - "name": "referrer-policy", - "value": "origin-when-cross-origin, strict-origin-when-cross-origin" - }, - { - "name": "content-security-policy", - "value": "default-src 'none'" - }, - { - "name": "content-encoding", - "value": "gzip" - }, - { - "name": "x-ratelimit-limit", - "value": "60" - }, - { - "name": "x-ratelimit-remaining", - "value": "50" - }, - { - "name": "x-ratelimit-reset", - "value": "1639796310" - }, - { - "name": "x-ratelimit-resource", - "value": "core" - }, - { - "name": "x-ratelimit-used", - "value": "10" - }, - { - "name": "accept-ranges", - "value": "bytes" - }, - { - "name": "content-length", - "value": "1395" - }, - { - "name": "x-github-request-id", - "value": "EEAE:63BE:99865:2DAECA:61BD4418" - }, - { - "name": "connection", - "value": "close" - } - ], - "headersSize": 1282, - "httpVersion": "HTTP/1.1", - "redirectURL": "", - "status": 200, - "statusText": "OK" - }, - "startedDateTime": "2021-12-18T02:14:47.816Z", - "time": 273, - "timings": { - "blocked": -1, - "connect": -1, - "dns": -1, - "receive": 0, - "send": 0, - "ssl": -1, - "wait": 273 - } - } - ], - "pages": [], - "version": "1.2" - } -} diff --git a/examples/typescript-jest-node-fetch/__recordings__/getUser-org-name_95565551/recording.har b/examples/typescript-jest-node-fetch/__recordings__/getUser-org-name_95565551/recording.har deleted file mode 100644 index 7bd27226..00000000 --- a/examples/typescript-jest-node-fetch/__recordings__/getUser-org-name_95565551/recording.har +++ /dev/null @@ -1,191 +0,0 @@ -{ - "log": { - "_recordingName": "getUser: org name", - "creator": { - "comment": "persister:fs", - "name": "Polly.JS", - "version": "5.1.1" - }, - "entries": [ - { - "_id": "87a2a6f326da043bea5bb7614c378003", - "_order": 0, - "cache": {}, - "request": { - "bodySize": 0, - "cookies": [], - "headers": [ - { - "_fromType": "array", - "name": "accept", - "value": "application/json+vnd.github.v3.raw" - }, - { - "_fromType": "array", - "name": "content-type", - "value": "application/json" - }, - { - "_fromType": "array", - "name": "user-agent", - "value": "node-fetch/1.0 (+https://github.com/bitinn/node-fetch)" - }, - { - "_fromType": "array", - "name": "accept-encoding", - "value": "gzip,deflate" - }, - { - "_fromType": "array", - "name": "connection", - "value": "close" - }, - { - "name": "host", - "value": "api.github.com" - } - ], - "headersSize": 270, - "httpVersion": "HTTP/1.1", - "method": "GET", - "queryString": [], - "url": "https://api.github.com/users/facebook" - }, - "response": { - "bodySize": 566, - "content": { - "_isBinary": true, - "mimeType": "application/json; charset=utf-8", - "size": 566, - "text": "[\"1f8b08000000000000039d53db8adb3010fd15a1e724be64b3ec0a4aa1d7a76c0a5de8362f41b6155b1b5963e4915337ecbf776487ad9b8742160cb6c59ccb8ce69cb881525b2e\",\"f85ee62a0338f019d70517b7f7b7cb64c62d146a17fef9fad3e77e73b8efb7e9172f9f9aaaf86abaecf9e7eae179fd8b30b29328ddce3b43b51562d38a281a0fdb45a9b1f2996f95cbc1a2b2b8c8a18e7c3488bcefdedd1041e9ce14831a1d5c5035fa4c336289ab8d269e2baccd85faa83a944f0af7600c1c097de9f57f02d12b8a8c8ddfda966f6020d42902ac148d8a5a78098deb16af3333204e5178d1dd048e9666ef547195a13386ec1c2d3939454e353090f9accd9d6e5083bdced83f486202574aab7fcbeb9908d91241b0749d85014148d5d19a5d071d21a7a871ba93791f46e154ae7447837d03dd0596d8b06f14edf6663295306e8d6a278b3aa4702f4dab2875b20e856b85920a68811b697b2eac3766c6334aec2463d028db8277b95aecb3b0ec8430900f331f38ac01f64dbac38c7d9446efc1591d58552d356575e4acb4533233247ad6d040d81f8a49a7d811dc81f69621b0cc6b533012a9bdd5d833ac1cf8b262c1041b5d30547965814cf60bf6f041b05ad519c58dd5be4556c94e313cc29c1289e098f4582dc2688e1af11c8a49f71be2fd3e3447358dcf8cce77e30d8b24495f8f864070114efe0655c493a8f2f0975393489729919a4be3f87e1edfcce3f4315e8ae54aa4e996447c534c6bd2649ed0133f2677627927e2d596bffc0129c9ebed34050000\"]" - }, - "cookies": [], - "headers": [ - { - "name": "server", - "value": "GitHub.com" - }, - { - "name": "date", - "value": "Sat, 18 Dec 2021 02:14:47 GMT" - }, - { - "name": "content-type", - "value": "application/json; charset=utf-8" - }, - { - "name": "cache-control", - "value": "public, max-age=60, s-maxage=60" - }, - { - "name": "vary", - "value": "Accept, Accept-Encoding, Accept, X-Requested-With" - }, - { - "name": "etag", - "value": "W/\"76fcb794577ec048f99f9d8f0d2cad3180c61288665ea43b7623b80c1dffd6ff\"" - }, - { - "name": "last-modified", - "value": "Wed, 10 Nov 2021 18:38:05 GMT" - }, - { - "name": "x-github-media-type", - "value": "github.v3; format=vnd.github.v3.raw" - }, - { - "name": "access-control-expose-headers", - "value": "ETag, Link, Location, Retry-After, X-GitHub-OTP, X-RateLimit-Limit, X-RateLimit-Remaining, X-RateLimit-Used, X-RateLimit-Resource, X-RateLimit-Reset, X-OAuth-Scopes, X-Accepted-OAuth-Scopes, X-Poll-Interval, X-GitHub-Media-Type, X-GitHub-SSO, X-GitHub-Request-Id, Deprecation, Sunset" - }, - { - "name": "access-control-allow-origin", - "value": "*" - }, - { - "name": "strict-transport-security", - "value": "max-age=31536000; includeSubdomains; preload" - }, - { - "name": "x-frame-options", - "value": "deny" - }, - { - "name": "x-content-type-options", - "value": "nosniff" - }, - { - "name": "x-xss-protection", - "value": "0" - }, - { - "name": "referrer-policy", - "value": "origin-when-cross-origin, strict-origin-when-cross-origin" - }, - { - "name": "content-security-policy", - "value": "default-src 'none'" - }, - { - "name": "content-encoding", - "value": "gzip" - }, - { - "name": "x-ratelimit-limit", - "value": "60" - }, - { - "name": "x-ratelimit-remaining", - "value": "51" - }, - { - "name": "x-ratelimit-reset", - "value": "1639796309" - }, - { - "name": "x-ratelimit-resource", - "value": "core" - }, - { - "name": "x-ratelimit-used", - "value": "9" - }, - { - "name": "accept-ranges", - "value": "bytes" - }, - { - "name": "content-length", - "value": "566" - }, - { - "name": "x-github-request-id", - "value": "EEAD:72E7:C2A4BD:146FA37:61BD4417" - }, - { - "name": "connection", - "value": "close" - } - ], - "headersSize": 1282, - "httpVersion": "HTTP/1.1", - "redirectURL": "", - "status": 200, - "statusText": "OK" - }, - "startedDateTime": "2021-12-18T02:14:47.562Z", - "time": 231, - "timings": { - "blocked": -1, - "connect": -1, - "dns": -1, - "receive": 0, - "send": 0, - "ssl": -1, - "wait": 231 - } - } - ], - "pages": [], - "version": "1.2" - } -} diff --git a/examples/typescript-jest-node-fetch/__recordings__/getUser_1648904580/recording.har b/examples/typescript-jest-node-fetch/__recordings__/getUser_1648904580/recording.har deleted file mode 100644 index fc96d720..00000000 --- a/examples/typescript-jest-node-fetch/__recordings__/getUser_1648904580/recording.har +++ /dev/null @@ -1,191 +0,0 @@ -{ - "log": { - "_recordingName": "getUser", - "creator": { - "comment": "persister:fs", - "name": "Polly.JS", - "version": "5.1.1" - }, - "entries": [ - { - "_id": "daab17694c1a59a0f3781977d2bf32d7", - "_order": 0, - "cache": {}, - "request": { - "bodySize": 0, - "cookies": [], - "headers": [ - { - "_fromType": "array", - "name": "accept", - "value": "application/json+vnd.github.v3.raw" - }, - { - "_fromType": "array", - "name": "content-type", - "value": "application/json" - }, - { - "_fromType": "array", - "name": "user-agent", - "value": "node-fetch/1.0 (+https://github.com/bitinn/node-fetch)" - }, - { - "_fromType": "array", - "name": "accept-encoding", - "value": "gzip,deflate" - }, - { - "_fromType": "array", - "name": "connection", - "value": "close" - }, - { - "name": "host", - "value": "api.github.com" - } - ], - "headersSize": 269, - "httpVersion": "HTTP/1.1", - "method": "GET", - "queryString": [], - "url": "https://api.github.com/users/netflix" - }, - "response": { - "bodySize": 525, - "content": { - "_isBinary": true, - "mimeType": "application/json; charset=utf-8", - "size": 525, - "text": "[\"1f8b080000000000000395935f6f9b3014c5bf0af2338981aceb8a146dd2fe5493d666d25aa9ca4b64c081bb1adbb20d2945fdeebb06b2647998c41360dddfb987eb7b7a22\",\"540992a4e49ebbbd8017121228487a13afaede5f8744aa82effc01b9fbf2b5db3cdf74dbe45bc39e7455dc8a36fbfdfc72f7fa98dc1fd66b0459cb1c33bbc608acaf9cd336a5743cb4cb125cd5648de52657d271e996b9aa6943c74e1fdbf53b5428cda431b4c4830b2d0d93ce08a398a527e395abc545f7b1eb507daadb2b21d401d94babff91a77f217435be832ce70b20d453e52a8e7342fb6ffea7c1ba595606a0a7fe8177e3252cceddf0628e9d09413307893e7a6ab856835693d9dc8076a0e42c5bff8028a44cc924bcb2d942085ae4bda15906060041dee27acd2247a2a7da40cbf2ce8fc1f09c438b339daf7681a298eb34c785de9c4dc44f1a1cdfb1a2f6f9db336139e68dd5be70dad530f82ef32556e2fe6a263b92ca4688906418da296298303926f7980c501409a1f261f058f643d9e0963965c3e03313b0574602f363aa19f8a44ebcb2f6d3510afb61410586b34ca0a1a92da893b760a3b90c7ea9c6e43cf82998435d0fb90338376df7f83723ac9b4c40be1bef284da20f21998e8675266974cc1506f3ec0b03337ce5e8c5e17530871e92288e17d1f5225e3d24118aa551bcc5de8d2ece6b926811278b287948927415a7abab2d79fb03b458ebc7f1040000\"]" - }, - "cookies": [], - "headers": [ - { - "name": "server", - "value": "GitHub.com" - }, - { - "name": "date", - "value": "Sat, 18 Dec 2021 02:51:42 GMT" - }, - { - "name": "content-type", - "value": "application/json; charset=utf-8" - }, - { - "name": "cache-control", - "value": "public, max-age=60, s-maxage=60" - }, - { - "name": "vary", - "value": "Accept, Accept-Encoding, Accept, X-Requested-With" - }, - { - "name": "etag", - "value": "W/\"e7c5ada389fe724c41d8b2248ede8e368c0fdd159f907ca79d9c0a78fa3344cb\"" - }, - { - "name": "last-modified", - "value": "Wed, 02 Dec 2020 22:31:35 GMT" - }, - { - "name": "x-github-media-type", - "value": "github.v3; format=vnd.github.v3.raw" - }, - { - "name": "access-control-expose-headers", - "value": "ETag, Link, Location, Retry-After, X-GitHub-OTP, X-RateLimit-Limit, X-RateLimit-Remaining, X-RateLimit-Used, X-RateLimit-Resource, X-RateLimit-Reset, X-OAuth-Scopes, X-Accepted-OAuth-Scopes, X-Poll-Interval, X-GitHub-Media-Type, X-GitHub-SSO, X-GitHub-Request-Id, Deprecation, Sunset" - }, - { - "name": "access-control-allow-origin", - "value": "*" - }, - { - "name": "strict-transport-security", - "value": "max-age=31536000; includeSubdomains; preload" - }, - { - "name": "x-frame-options", - "value": "deny" - }, - { - "name": "x-content-type-options", - "value": "nosniff" - }, - { - "name": "x-xss-protection", - "value": "0" - }, - { - "name": "referrer-policy", - "value": "origin-when-cross-origin, strict-origin-when-cross-origin" - }, - { - "name": "content-security-policy", - "value": "default-src 'none'" - }, - { - "name": "content-encoding", - "value": "gzip" - }, - { - "name": "x-ratelimit-limit", - "value": "60" - }, - { - "name": "x-ratelimit-remaining", - "value": "49" - }, - { - "name": "x-ratelimit-reset", - "value": "1639796310" - }, - { - "name": "x-ratelimit-resource", - "value": "core" - }, - { - "name": "x-ratelimit-used", - "value": "11" - }, - { - "name": "accept-ranges", - "value": "bytes" - }, - { - "name": "content-length", - "value": "525" - }, - { - "name": "x-github-request-id", - "value": "F0FE:59E5:11836D1:2EFAA44:61BD4CBE" - }, - { - "name": "connection", - "value": "close" - } - ], - "headersSize": 1284, - "httpVersion": "HTTP/1.1", - "redirectURL": "", - "status": 200, - "statusText": "OK" - }, - "startedDateTime": "2021-12-18T02:51:41.766Z", - "time": 288, - "timings": { - "blocked": -1, - "connect": -1, - "dns": -1, - "receive": 0, - "send": 0, - "ssl": -1, - "wait": 288 - } - } - ], - "pages": [], - "version": "1.2" - } -} diff --git a/examples/typescript-jest-node-fetch/jest.config.ts b/examples/typescript-jest-node-fetch/jest.config.ts index 0501c168..16b27066 100644 --- a/examples/typescript-jest-node-fetch/jest.config.ts +++ b/examples/typescript-jest-node-fetch/jest.config.ts @@ -1,6 +1,5 @@ import type { Config } from "@jest/types"; -// Sync object const config: Config.InitialOptions = { rootDir: ".", preset: "ts-jest", diff --git a/examples/typescript-jest-node-fetch/package.json b/examples/typescript-jest-node-fetch/package.json index 8911860c..9533c9ce 100644 --- a/examples/typescript-jest-node-fetch/package.json +++ b/examples/typescript-jest-node-fetch/package.json @@ -2,7 +2,7 @@ "name": "typescript-jest-node-fetch", "version": "1.0.0", "private": true, - "main": "index.js", + "main": "./dist/index.js", "type": "commonjs", "exports": "./dist/index.js", "scripts": { diff --git a/examples/typescript-jest-node-fetch/src/github-api.test.ts b/examples/typescript-jest-node-fetch/src/github-api.test.ts index 65641625..a468ba83 100644 --- a/examples/typescript-jest-node-fetch/src/github-api.test.ts +++ b/examples/typescript-jest-node-fetch/src/github-api.test.ts @@ -5,12 +5,12 @@ import { getUser } from "./github-api"; // 🟡 Important: Run `autoSetupPolly()`/`setupPolly()` EARLY! let pollyContext = autoSetupPolly(); /* Polly/Nock MUST patch HTTP modules before your code `import`'s or `require`'s those modules. -✅ Place after `import`'s, OR at the top of first `describe()`. -❌ Do NOT setup in `beforeAll`/`beforeEach`! +✅ Place autoSetupPolly() after `import`'s, OR at the top of first `describe()`. +❌ Do NOT autoSetupPolly() in `beforeAll`/`beforeEach`! */ // beforeEach(() => { -// // Common or shared interceptors go here. +// // Common or shared interceptors go here, or in tests. See example below. // pollyContext.polly.server // .get("/ping") // .intercept((req, res) => void res.sendStatus(200)); diff --git a/examples/typescript-jest-node-fetch/src/utils/auto-setup-polly.ts b/examples/typescript-jest-node-fetch/src/utils/auto-setup-polly.ts index 9a64a7e7..3c8562b6 100644 --- a/examples/typescript-jest-node-fetch/src/utils/auto-setup-polly.ts +++ b/examples/typescript-jest-node-fetch/src/utils/auto-setup-polly.ts @@ -27,11 +27,11 @@ export default function autoSetupPolly() { // 🟡 Note: In node, all `fetch` like libraries use the http/https modules under the hood. // `node-fetch` is handled by the `NodeHttpAdapter`, NOT the `FetchAdapter`. adapters: ["node-http"], - mode: pollyMode, - recordIfMissing, - recordFailedRequests: true, flushRequestsOnStop: true, logging: false, + mode: pollyMode, + recordFailedRequests: true, + recordIfMissing, persister: "fs", persisterOptions: { fs: { From 9a23fa43f82febc3284a8f9a653c7b55307eb3c5 Mon Sep 17 00:00:00 2001 From: Dan Levy Date: Sun, 19 Dec 2021 17:50:17 -0700 Subject: [PATCH 3/7] chore: remove unnecessary dotfiles. --- .../typescript-jest-node-fetch/.gitignore | 126 ------------------ 1 file changed, 126 deletions(-) delete mode 100644 examples/typescript-jest-node-fetch/.gitignore diff --git a/examples/typescript-jest-node-fetch/.gitignore b/examples/typescript-jest-node-fetch/.gitignore deleted file mode 100644 index 320e8538..00000000 --- a/examples/typescript-jest-node-fetch/.gitignore +++ /dev/null @@ -1,126 +0,0 @@ -# Logs -logs -*.log -npm-debug.log* -yarn-debug.log* -yarn-error.log* -lerna-debug.log* -.pnpm-debug.log* - -# Diagnostic reports (https://nodejs.org/api/report.html) -report.[0-9]*.[0-9]*.[0-9]*.[0-9]*.json - -# Runtime data -pids -*.pid -*.seed -*.pid.lock - -# Directory for instrumented libs generated by jscoverage/JSCover -lib-cov - -# Coverage directory used by tools like istanbul -coverage -*.lcov - -# nyc test coverage -.nyc_output - -# Grunt intermediate storage (https://gruntjs.com/creating-plugins#storing-task-files) -.grunt - -# Bower dependency directory (https://bower.io/) -bower_components - -# node-waf configuration -.lock-wscript - -# Compiled binary addons (https://nodejs.org/api/addons.html) -build/Release - -# Dependency directories -node_modules -jspm_packages/ - -# Snowpack dependency directory (https://snowpack.dev/) -web_modules/ - -# TypeScript cache -*.tsbuildinfo - -# Optional npm cache directory -.npm - -# Optional eslint cache -.eslintcache - -# Optional stylelint cache -.stylelintcache - -# Microbundle cache -.rpt2_cache/ -.rts2_cache_cjs/ -.rts2_cache_es/ -.rts2_cache_umd/ - -# Optional REPL history -.node_repl_history - -# Output of 'npm pack' -*.tgz - -# Yarn Integrity file -.yarn-integrity - -# dotenv environment variables file -.env.development.local -.env.test.local -.env.production.local -.env.local - -# parcel-bundler cache (https://parceljs.org/) -.cache -.parcel-cache - -# Next.js build output -.next -out - -# Nuxt.js build / generate output -.nuxt -dist - -# Gatsby files -.cache/ -# Comment in the public line in if your project uses Gatsby and not Next.js -# https://nextjs.org/blog/next-9-1#public-directory-support -# public - -# vuepress build output -.vuepress/dist - -# vuepress v2.x temp and cache directory -.temp -.cache - -# Serverless directories -.serverless/ - -# FuseBox cache -.fusebox/ - -# DynamoDB Local files -.dynamodb/ - -# TernJS port file -.tern-port - -# Stores VSCode versions used for testing VSCode extensions -.vscode-test - -# yarn v2 -.yarn/cache -.yarn/unplugged -.yarn/build-state.yml -.yarn/install-state.gz -.pnp.* From ede513ef8fcb71252f07c7e5a1e0c97b92b946e5 Mon Sep 17 00:00:00 2001 From: Dan Levy Date: Wed, 22 Dec 2021 10:15:55 -0700 Subject: [PATCH 4/7] docs: Updated docs site --- docs/examples.md | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/docs/examples.md b/docs/examples.md index 8ee282d2..4f99c189 100644 --- a/docs/examples.md +++ b/docs/examples.md @@ -34,6 +34,14 @@ [index.test.js](https://raw.githubusercontent.com/Netflix/pollyjs/master/examples/jest-node-fetch/__tests__/index.test.js ':include :type=code') +## TypeScript + Jest + Node Fetch + +**[Full Source](https://github.com/Netflix/pollyjs/tree/master/examples/typescript-jest-node-fetch)** + +[auto-setup-polly.ts](https://raw.githubusercontent.com/Netflix/pollyjs/master/examples/typescript-jest-node-fetch/src/utils/auto-setup-polly.ts ':include :type=code') + +[github-api.test.ts](https://raw.githubusercontent.com/Netflix/pollyjs/master/examples/typescript-jest-node-fetch/src/github-api.test.ts ':include :type=code') + ## Jest + Puppeteer **[Full Source](https://github.com/Netflix/pollyjs/tree/master/examples/jest-puppeteer)** From 4bf2fe326595233b51372bb32df1f41963f984a9 Mon Sep 17 00:00:00 2001 From: Dan Levy <397632+justsml@users.noreply.github.com> Date: Mon, 7 Feb 2022 13:27:34 -0700 Subject: [PATCH 5/7] Remove comments --- examples/typescript-jest-node-fetch/tsconfig.json | 2 -- 1 file changed, 2 deletions(-) diff --git a/examples/typescript-jest-node-fetch/tsconfig.json b/examples/typescript-jest-node-fetch/tsconfig.json index 49004663..06fc9006 100644 --- a/examples/typescript-jest-node-fetch/tsconfig.json +++ b/examples/typescript-jest-node-fetch/tsconfig.json @@ -2,7 +2,6 @@ "compilerOptions": { "target": "ES5", "lib": ["esnext"], - // "extendedDiagnostics": true, "allowJs": true, "skipLibCheck": true, "esModuleInterop": true, @@ -15,7 +14,6 @@ "moduleResolution": "node", "resolveJsonModule": true, "isolatedModules": true, - // "noEmit": true, "sourceMap": true, "baseUrl": ".", "rootDir": ".", From 08c460919e24ba9fe0fafce818fa3619fba40b0f Mon Sep 17 00:00:00 2001 From: Dan Levy <397632+justsml@users.noreply.github.com> Date: Mon, 7 Feb 2022 13:30:07 -0700 Subject: [PATCH 6/7] Remove comments --- .../typescript-jest-node-fetch/src/utils/auto-setup-polly.ts | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/examples/typescript-jest-node-fetch/src/utils/auto-setup-polly.ts b/examples/typescript-jest-node-fetch/src/utils/auto-setup-polly.ts index 3c8562b6..34af623b 100644 --- a/examples/typescript-jest-node-fetch/src/utils/auto-setup-polly.ts +++ b/examples/typescript-jest-node-fetch/src/utils/auto-setup-polly.ts @@ -3,8 +3,7 @@ import { setupPolly } from "setup-polly-jest"; import { Polly } from "@pollyjs/core"; import NodeHttpAdapter from "@pollyjs/adapter-node-http"; import FSPersister from "@pollyjs/persister-fs"; -// import FetchAdapter from "@pollyjs/adapter-fetch"; -// Polly.register(FetchAdapter); + Polly.register(NodeHttpAdapter); Polly.register(FSPersister); @@ -48,4 +47,4 @@ If you have trouble initializing/loading the interceptors early enough, try a si 2. Add a new line: `export default autoSetupPolly();` Then when you `import` this module it will execute roughly immediately, and the default export will be the Context. -*/ \ No newline at end of file +*/ From e5b2f6209ca4c3996730d76ed4a9adcdfb2f027c Mon Sep 17 00:00:00 2001 From: Dan Levy Date: Fri, 18 Feb 2022 23:07:30 -0700 Subject: [PATCH 7/7] refactor: Cleaning up POLLY_MODE logic --- .../getUser_1648904580/recording.har | 191 ++++++++++++++++++ .../src/github-api.test.ts | 49 +++-- .../src/utils/auto-setup-polly.ts | 45 ++--- 3 files changed, 236 insertions(+), 49 deletions(-) create mode 100644 examples/typescript-jest-node-fetch/__recordings__/github-api-client_2139812550/getUser_1648904580/recording.har diff --git a/examples/typescript-jest-node-fetch/__recordings__/github-api-client_2139812550/getUser_1648904580/recording.har b/examples/typescript-jest-node-fetch/__recordings__/github-api-client_2139812550/getUser_1648904580/recording.har new file mode 100644 index 00000000..2ffc5943 --- /dev/null +++ b/examples/typescript-jest-node-fetch/__recordings__/github-api-client_2139812550/getUser_1648904580/recording.har @@ -0,0 +1,191 @@ +{ + "log": { + "_recordingName": "github-api client/getUser", + "creator": { + "comment": "persister:fs", + "name": "Polly.JS", + "version": "5.1.1" + }, + "entries": [ + { + "_id": "daab17694c1a59a0f3781977d2bf32d7", + "_order": 0, + "cache": {}, + "request": { + "bodySize": 0, + "cookies": [], + "headers": [ + { + "_fromType": "array", + "name": "accept", + "value": "application/json+vnd.github.v3.raw" + }, + { + "_fromType": "array", + "name": "content-type", + "value": "application/json" + }, + { + "_fromType": "array", + "name": "user-agent", + "value": "node-fetch/1.0 (+https://github.com/bitinn/node-fetch)" + }, + { + "_fromType": "array", + "name": "accept-encoding", + "value": "gzip,deflate" + }, + { + "_fromType": "array", + "name": "connection", + "value": "close" + }, + { + "name": "host", + "value": "api.github.com" + } + ], + "headersSize": 269, + "httpVersion": "HTTP/1.1", + "method": "GET", + "queryString": [], + "url": "https://api.github.com/users/netflix" + }, + "response": { + "bodySize": 525, + "content": { + "_isBinary": true, + "mimeType": "application/json; charset=utf-8", + "size": 525, + "text": "[\"1f8b080000000000000395935f6f9b3014c5bf0af2338981aceb8a146dd2fe5493d666d25aa9ca4b64c081bb1adbb20d2945fdeebb06b2647998c41360dddfb987eb7b7a2254\",\"0992a4e49ebbbd8017121228487a13afaede5f8744aa82effc01b9fbf2b5db3cdf74dbe45bc39e7455dc8a36fbfdfc72f7fa98dc1fd66b0459cb1c33bbc608acaf9cd336a5743cb4cb125cd5648de52657d271e996b9aa6943c74e1fdbf53b5428cda431b4c4830b2d0d93ce08a398a527e395abc545f7b1eb507daadb2b21d401d94babff91a77f217435be832ce70b20d453e52a8e7342fb6ffea7c1ba595606a0a7fe8177e3252cceddf0628e9d09413307893e7a6ab856835693d9dc8076a0e42c5bff8028a44cc924bcb2d942085ae4bda15906060041dee27acd2247a2a7da40cbf2ce8fc1f09c438b339daf7681a298eb34c785de9c4dc44f1a1cdfb1a2f6f9db336139e68dd5be70dad530f82ef32556e2fe6a263b92ca4688906418da296298303926f7980c501409a1f261f058f643d9e0963965c3e03313b0574602f363aa19f8a44ebcb2f6d3510afb61410586b34ca0a1a92da893b760a3b90c7ea9c6e43cf82998435d0fb90338376df7f83723ac9b4c40be1bef284da20f21998e8675266974cc1506f3ec0b03337ce5e8c5e17530871e92288e17d1f5225e3d24118aa551bcc5de8d2ece6b926811278b287948927415a7abab2d79fb03b458ebc7f1040000\"]" + }, + "cookies": [], + "headers": [ + { + "name": "server", + "value": "GitHub.com" + }, + { + "name": "date", + "value": "Sat, 19 Feb 2022 05:56:54 GMT" + }, + { + "name": "content-type", + "value": "application/json; charset=utf-8" + }, + { + "name": "cache-control", + "value": "public, max-age=60, s-maxage=60" + }, + { + "name": "vary", + "value": "Accept, Accept-Encoding, Accept, X-Requested-With" + }, + { + "name": "etag", + "value": "W/\"e7c5ada389fe724c41d8b2248ede8e368c0fdd159f907ca79d9c0a78fa3344cb\"" + }, + { + "name": "last-modified", + "value": "Wed, 02 Dec 2020 22:31:35 GMT" + }, + { + "name": "x-github-media-type", + "value": "github.v3; format=vnd.github.v3.raw" + }, + { + "name": "access-control-expose-headers", + "value": "ETag, Link, Location, Retry-After, X-GitHub-OTP, X-RateLimit-Limit, X-RateLimit-Remaining, X-RateLimit-Used, X-RateLimit-Resource, X-RateLimit-Reset, X-OAuth-Scopes, X-Accepted-OAuth-Scopes, X-Poll-Interval, X-GitHub-Media-Type, X-GitHub-SSO, X-GitHub-Request-Id, Deprecation, Sunset" + }, + { + "name": "access-control-allow-origin", + "value": "*" + }, + { + "name": "strict-transport-security", + "value": "max-age=31536000; includeSubdomains; preload" + }, + { + "name": "x-frame-options", + "value": "deny" + }, + { + "name": "x-content-type-options", + "value": "nosniff" + }, + { + "name": "x-xss-protection", + "value": "0" + }, + { + "name": "referrer-policy", + "value": "origin-when-cross-origin, strict-origin-when-cross-origin" + }, + { + "name": "content-security-policy", + "value": "default-src 'none'" + }, + { + "name": "content-encoding", + "value": "gzip" + }, + { + "name": "x-ratelimit-limit", + "value": "60" + }, + { + "name": "x-ratelimit-remaining", + "value": "59" + }, + { + "name": "x-ratelimit-reset", + "value": "1645253814" + }, + { + "name": "x-ratelimit-resource", + "value": "core" + }, + { + "name": "x-ratelimit-used", + "value": "1" + }, + { + "name": "accept-ranges", + "value": "bytes" + }, + { + "name": "content-length", + "value": "525" + }, + { + "name": "x-github-request-id", + "value": "F38D:0289:2486BB0:45D7297:621086A6" + }, + { + "name": "connection", + "value": "close" + } + ], + "headersSize": 1283, + "httpVersion": "HTTP/1.1", + "redirectURL": "", + "status": 200, + "statusText": "OK" + }, + "startedDateTime": "2022-02-19T05:56:54.149Z", + "time": 454, + "timings": { + "blocked": -1, + "connect": -1, + "dns": -1, + "receive": 0, + "send": 0, + "ssl": -1, + "wait": 454 + } + } + ], + "pages": [], + "version": "1.2" + } +} diff --git a/examples/typescript-jest-node-fetch/src/github-api.test.ts b/examples/typescript-jest-node-fetch/src/github-api.test.ts index a468ba83..5dff6e20 100644 --- a/examples/typescript-jest-node-fetch/src/github-api.test.ts +++ b/examples/typescript-jest-node-fetch/src/github-api.test.ts @@ -1,32 +1,31 @@ /** @jest-environment setup-polly-jest/jest-environment-node */ -import autoSetupPolly from "./utils/auto-setup-polly"; -import { getUser } from "./github-api"; +import autoSetupPolly from './utils/auto-setup-polly'; +import { getUser } from './github-api'; -// 🟡 Important: Run `autoSetupPolly()`/`setupPolly()` EARLY! -let pollyContext = autoSetupPolly(); -/* Polly/Nock MUST patch HTTP modules before your code `import`'s or `require`'s those modules. -✅ Place autoSetupPolly() after `import`'s, OR at the top of first `describe()`. -❌ Do NOT autoSetupPolly() in `beforeAll`/`beforeEach`! -*/ +describe('github-api client', () => { + let pollyContext = autoSetupPolly(); -// beforeEach(() => { -// // Common or shared interceptors go here, or in tests. See example below. -// pollyContext.polly.server -// .get("/ping") -// .intercept((req, res) => void res.sendStatus(200)); -// }); + beforeEach(() => { + // Intercept /ping healthcheck requests (example) + pollyContext.polly.server + .any("/ping") + .intercept((req, res) => void res.sendStatus(200)); + }); -test("getUser", async () => { - const user: any = await getUser("netflix"); - expect(typeof user).toBe("object"); - expect(user?.login).toBe("Netflix"); -}); + it('getUser', async () => { + const user: any = await getUser('netflix'); + expect(typeof user).toBe('object'); + expect(user?.login).toBe('Netflix'); + }); -test("getUser: custom interceptor", async () => { - expect.assertions(1); - pollyContext.polly.server - .get("https://api.github.com/users/failing_request_trigger") - .intercept((req, res) => void res.sendStatus(500)); + it('getUser: custom interceptor', async () => { + expect.assertions(1); + pollyContext.polly.server + .get('https://api.github.com/users/failing_request_trigger') + .intercept((req, res) => void res.sendStatus(500)); - await expect(getUser("failing_request_trigger")).rejects.toThrow('Http Error: 500'); + await expect(getUser('failing_request_trigger')).rejects.toThrow( + 'Http Error: 500' + ); + }); }); diff --git a/examples/typescript-jest-node-fetch/src/utils/auto-setup-polly.ts b/examples/typescript-jest-node-fetch/src/utils/auto-setup-polly.ts index 3c8562b6..debc02bc 100644 --- a/examples/typescript-jest-node-fetch/src/utils/auto-setup-polly.ts +++ b/examples/typescript-jest-node-fetch/src/utils/auto-setup-polly.ts @@ -1,37 +1,43 @@ import path from "path"; import { setupPolly } from "setup-polly-jest"; -import { Polly } from "@pollyjs/core"; +import { Polly, PollyConfig } from "@pollyjs/core"; import NodeHttpAdapter from "@pollyjs/adapter-node-http"; import FSPersister from "@pollyjs/persister-fs"; -// import FetchAdapter from "@pollyjs/adapter-fetch"; -// Polly.register(FetchAdapter); + Polly.register(NodeHttpAdapter); Polly.register(FSPersister); -const {POLLY_MODE} = process.env; - let recordIfMissing = true; -if (POLLY_MODE === "offline") recordIfMissing = false; +let mode: PollyConfig['mode'] = 'replay'; -const pollyMode = POLLY_MODE === "record" ? "record" - : POLLY_MODE === "offline" ? "replay" - : "replay"; // Default is "replay" +switch (process.env.POLLY_MODE) { + case 'record': + mode = 'record'; + break; + case 'replay': + mode = 'replay'; + break; + case 'offline': + mode = 'replay'; + recordIfMissing = false; + break; +} export default function autoSetupPolly() { /** - * NOTE: Customize your config here, usually differs per project. - * * This persister can be adapted for both Node.js and Browser environments. + * + * TODO: Customize your config. */ return setupPolly({ - // 🟡 Note: In node, all `fetch` like libraries use the http/https modules under the hood. - // `node-fetch` is handled by the `NodeHttpAdapter`, NOT the `FetchAdapter`. + // 🟡 Note: In node, most `fetch` like libraries use the http/https modules. + // `node-fetch` is handled by `NodeHttpAdapter`, NOT the `FetchAdapter`. adapters: ["node-http"], + mode, + recordIfMissing, flushRequestsOnStop: true, logging: false, - mode: pollyMode, recordFailedRequests: true, - recordIfMissing, persister: "fs", persisterOptions: { fs: { @@ -40,12 +46,3 @@ export default function autoSetupPolly() { }, }); } - -/* -If you have trouble initializing/loading the interceptors early enough, try a singleton pattern for this module: - -1. Remove the `export default` here: `export default function autoSetupPolly() {:` -2. Add a new line: `export default autoSetupPolly();` - -Then when you `import` this module it will execute roughly immediately, and the default export will be the Context. -*/ \ No newline at end of file