mirror of
https://github.com/Kong/insomnia.git
synced 2026-10-25 16:19:20 -04:00
Api V2 (#6135)
* Add support for multiple remote projects per Team (#6009) * update fetching of teams * create and delete remote projects * backend project sync using the new teamProjectId in the API * indicator * use team api to get organization data * handle logged out state * remove remote from duplicate modal * remaining insomnia fetch fixes * fix ts issues * fix ts log issue * fix ts error * fix ts update * fix tests * remove log * add types to insomniaFetch * named arguments in vcs --------- Co-authored-by: jackkav <jackkav@gmail.com> * Project Presence (#6079) * fix ts log issue * fix ts update * update fetching of teams * create and delete remote projects * real-time * update api changes * check for successful response * get user profile * cleanup * update fetch * update network status * fix for insomniaFetch new api * insomnia fetch from window * fix missing stat * fix project dropdown * update avatar * update presence when closing the app * update the presence every minute * cleanup presence * use eventsource and improve debugging * Cloud only projects (#6167) * Add support for multiple remote projects per Team (#6009) * update fetching of teams * create and delete remote projects * backend project sync using the new teamProjectId in the API * indicator * use team api to get organization data * handle logged out state * remove remote from duplicate modal * remaining insomnia fetch fixes * fix ts issues * fix ts log issue * fix ts error * fix ts update * fix tests * remove log * add types to insomniaFetch * named arguments in vcs --------- Co-authored-by: jackkav <jackkav@gmail.com> * login routes * cleanup logged in state * update organizations * fixes * update migration * auto init sync on workspaces without git * fix auto init sync * checkpoint * update import options in empty project pane * responsive styles * update package-lock * join an org in sidebar * readability improvements * move modals and root loader to org * cleanup root * expire session take 1 * cleanup default org id * fix ts issue --------- Co-authored-by: jackkav <jackkav@gmail.com> * Add Scratch Pad collection (#6221) * add scratchpad collection * filter scratchpad from cloud migration * disable sync for scratchpad * update settings for scratchpad * log in rename * check if user is logged in or has logged in before * use organization api * organizations api fixes * update urls * move modals to root * update org navbar links * lint fix * type-check * Add form for setting up the staging env * add autolinking * onboarding * remove default org id * staging urls * avatar styles * update urls * use display name for orgs * update settings modal with dev * proper project deletions * fix api calls perf * sidebar improvements * layout styles * disable tests for now * fix boolean * fix data migration * dev settings styles * test init * organization names * link styles * improve scratchpad banner styles * http colors * url bar styles * spinner styles * breadcrumbs styles * help and feedback links * settings to root * onboarding * fetch remote projects on org nav * update avatar styles * use name initials in avatars * don't allow to delete default organization project * add scratchpad checks * tests * workspace settings tabs types * export all workspaces * fix types and personal org * project permission checks * continue with sso * organization avatars * project presence avatars * fix privacy/terms links * add the no-wrap classname * update user name and email in the app * fix delete action * ai fetching * generate tests in sequence to help with rate limiting * wip testing * wip test * improve test and migration script * fix ts * local to cloud projects test * set local-to-cloud-projects.test as slow * fix e2e tests * update settings tests * update more apis that changed from teams -> organizations * simplify remote project migration * org.branding can be undefined * fix imports issue in sr * remove .only * remove unused gql query * fix onboarding height jump * trust some rnd and upload artifacts on failure * fix env vars replacement on prod * fix constant name * bring back checks * fix inso test * add temp changes * fix inconsistent response handling * handle bad auth code errors * show email when logged in * remove the concept of default_project * cleanup auth styles * fix: use scratchpad constants wherever needed and remove seed * fix sentry lint error * migrate with update * add scratch pad fixture and typing * refactor pushSnapshotOnInitialize to always work * remove console.log * remove account from preferences * improve trail-lines styles * fix project sidebar scroll issue * only create diff of projects * fix lint * sync * feat: add plan upgrading modal for git sync (#6516) * feat: add plan upgrading modal for git sync * feat: add plan upgrading modal to project git menu and grid menu * fix: use JSON.parse for getting flag value * update ask modal * remove git option from workspace settings --------- Co-authored-by: gatzjames <jamesgatzos@gmail.com> * sort projectswith default at top * create local copies of remotes * update presence exit update * renames * fix deleting/renaming projects with remoteId * remoteId instead of projectId * remote-collections * fix initializeProjectForTeam * fix missing parentId in remote projects * add missing billing api * add migration page and check for migrations * cleanup project sync logic * fix remote projects updating * add notes * fix backend-project test * fix: use features API for fetching feature list (#6538) * members -> collaborators * remove dev settings * use shouldRunMigrations in onboarding * fix empty pane styles * remove beforeUnload for presence * show expiry info * better error for upgrade in new project action * extend retry period * fallback and control revalidate * add pending indicator for switching organizations * fix exports (#6553) * Sync Organizations (#6551) * organization cache and updates * error handling in org sync * sort organizations * clean up sort * org sort and avatar fallback --------- Co-authored-by: jackkav <jackkav@gmail.com> * Presence updates (#6552) * use remoteId for presence * use project loader for the active project * fix in present users * logic clean * match remoteId checks --------- Co-authored-by: jackkav <jackkav@gmail.com> * add default color to loading indicator * fix redirect loop when there are no projects * scratchpad fallback on initial route load * re-enable ai check * update error in renameProject * db query to get projects in workspace * review fix * comments * remove initModelFrom magic * fix lint issue --------- Co-authored-by: jackkav <jackkav@gmail.com> Co-authored-by: Mark Kim <mark.kim@konghq.com> Co-authored-by: Filipe Freire <livrofubia@gmail.com> Co-authored-by: Hexxa <hexxa@outlook.com>
This commit is contained in:
204 files changed
+5927
-2298
No files matched your search
@@ -18,8 +18,6 @@ concurrency:
|
||||
jobs:
|
||||
Test:
|
||||
runs-on: ubuntu-latest
|
||||
strategy:
|
||||
fail-fast: false
|
||||
steps:
|
||||
- name: Checkout branch
|
||||
uses: actions/checkout@v3
|
||||
@@ -103,8 +101,10 @@ jobs:
|
||||
- name: Smoke test Inso CLI
|
||||
run: npm run test:smoke:cli
|
||||
|
||||
# This step should always run even when previous steps fail
|
||||
- name: Upload smoke test traces
|
||||
uses: actions/upload-artifact@v3
|
||||
if: failure()
|
||||
with:
|
||||
if-no-files-found: ignore
|
||||
name: ubuntu-smoke-test-traces-${{ github.run_number }}
|
||||
|
||||
Vendored
+3
@@ -9,4 +9,7 @@
|
||||
"editor.formatOnSave": true,
|
||||
"editor.formatOnSaveMode": "modifications",
|
||||
"editor.defaultFormatter": "vscode.typescript-language-features",
|
||||
"[json]": {
|
||||
"editor.defaultFormatter": "vscode.json-language-features"
|
||||
},
|
||||
}
|
||||
Generated
+6
@@ -13888,6 +13888,11 @@
|
||||
"@grpc/grpc-js": "^1.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/gsap": {
|
||||
"version": "3.12.2",
|
||||
"resolved": "https://registry.npmjs.org/gsap/-/gsap-3.12.2.tgz",
|
||||
"integrity": "sha512-EkYnpG8qHgYBFAwsgsGEqvT1WUidX0tt/ijepx7z8EUJHElykg91RvW1XbkT59T0gZzzszOpjQv7SE41XuIXyQ=="
|
||||
},
|
||||
"node_modules/har-schema": {
|
||||
"version": "2.0.0",
|
||||
"resolved": "https://registry.npmjs.org/har-schema/-/har-schema-2.0.0.tgz",
|
||||
@@ -24562,6 +24567,7 @@
|
||||
"electron-context-menu": "^3.6.1",
|
||||
"electron-log": "^4.4.8",
|
||||
"grpc-reflection-js": "0.3.0",
|
||||
"gsap": "^3.11.3",
|
||||
"hawk": "9.0.1",
|
||||
"hkdf": "^0.0.2",
|
||||
"hosted-git-info": "5.2.1",
|
||||
|
||||
File diff suppressed because one or more lines are too long.
Whitespace-only changes.
Whitespace-only changes.
@@ -0,0 +1,8 @@
|
||||
{"_id":"jar_477c547643674a53b75ec94371a59119","type":"CookieJar","parentId":"wrk_1b49626a0a9442b7b9474a1f3493bb5d","modified":1694513741482,"created":1694513741482,"name":"Default Jar","cookies":[]}
|
||||
{"_id":"jar_5715ba490d323a1c17eddd5670b87527f86c23df","type":"CookieJar","parentId":"wrk_a528e60334a54420a7b384bae215ad1b","modified":1694436050045,"created":1694436050045,"name":"Default Jar","cookies":[]}
|
||||
{"_id":"jar_727e68a0650a9198b46e09fe922ebdf2c4b14ee9","type":"CookieJar","parentId":"wrk_f3246c005c9d48ed9e35724415c962d6","modified":1694435944034,"created":1694435944034,"name":"Default Jar","cookies":[]}
|
||||
{"_id":"jar_7b77a9be2508777ca03ff78df0ae609fc5f582bd","type":"CookieJar","parentId":"wrk_3f71ff5dcf5343169b9a67236f9deafe","modified":1694513691440,"created":1694513691440,"name":"Default Jar","cookies":[]}
|
||||
{"_id":"jar_ab007691f15cfc166d22b053624849abab40c5f7","type":"CookieJar","parentId":"wrk_ef815fde95ce489aa225fc4408a04bf7","modified":1694436238621,"created":1694436238621,"name":"Default Jar","cookies":[]}
|
||||
{"_id":"jar_b289a3371fe1228038a8a1df06cc2d0934f6b4f3","type":"CookieJar","parentId":"wrk_55a8240d025044d3a40eb40956126bec","modified":1694513468821,"created":1694513468821,"name":"Default Jar","cookies":[]}
|
||||
{"_id":"jar_ce5c6ddfabc8dac33df7b4d14509356c9d280eb8","type":"CookieJar","parentId":"wrk_7c9f917b97cb4a43bb402ace6df1b107","modified":1694513835062,"created":1694513835062,"name":"Default Jar","cookies":[]}
|
||||
{"_id":"jar_dfc984a037a5edccac6000064716590ad1628ad9","type":"CookieJar","parentId":"wrk_d783eca2fa46457c9f02a221ec862458","modified":1694513890792,"created":1694513890792,"name":"Default Jar","cookies":[]}
|
||||
@@ -0,0 +1,12 @@
|
||||
{"_id":"env_05e568304a74414b8b19bec3bae0e38d","type":"Environment","parentId":"env_5715ba490d323a1c17eddd5670b87527f86c23df","modified":1694436082762,"created":1694436082762,"name":"OpenAPI env petstore.swagger.io","data":{"scheme":"https","base_path":"/v2","host":"petstore.swagger.io"},"dataPropertyOrder":null,"color":null,"isPrivate":false,"metaSortKey":1694436082762}
|
||||
{"_id":"env_284ec449cf894ffd958b9b54ad598c02","type":"Environment","parentId":"wrk_1b49626a0a9442b7b9474a1f3493bb5d","modified":1694513741462,"created":1694513741462,"name":"Base Environment","data":{},"dataPropertyOrder":null,"color":null,"isPrivate":false,"metaSortKey":1694513468817}
|
||||
{"_id":"env_5715ba490d323a1c17eddd5670b87527f86c23df","type":"Environment","parentId":"wrk_a528e60334a54420a7b384bae215ad1b","modified":1694436050043,"created":1694436050043,"name":"Base Environment","data":{},"dataPropertyOrder":null,"color":null,"isPrivate":false,"metaSortKey":1694436050043}
|
||||
{"_id":"env_727e68a0650a9198b46e09fe922ebdf2c4b14ee9","type":"Environment","parentId":"wrk_f3246c005c9d48ed9e35724415c962d6","modified":1694436015076,"created":1694435944033,"name":"Base Environment","data":{"planet":"earth"},"dataPropertyOrder":{"&":["planet"]},"color":null,"isPrivate":false,"metaSortKey":1694435944033}
|
||||
{"_id":"env_7b77a9be2508777ca03ff78df0ae609fc5f582bd","type":"Environment","parentId":"wrk_3f71ff5dcf5343169b9a67236f9deafe","modified":1694513691435,"created":1694513691435,"name":"Base Environment","data":{},"dataPropertyOrder":null,"color":null,"isPrivate":false,"metaSortKey":1694513691435}
|
||||
{"_id":"env_84795a9d18884f0fa11582cc88c0f206","type":"Environment","parentId":"env_b289a3371fe1228038a8a1df06cc2d0934f6b4f3","modified":1694513478190,"created":1694513478190,"name":"OpenAPI env petstore.swagger.io","data":{"scheme":"https","base_path":"/v2","host":"petstore.swagger.io"},"dataPropertyOrder":null,"color":null,"isPrivate":false,"metaSortKey":1694513478190}
|
||||
{"_id":"env_ab007691f15cfc166d22b053624849abab40c5f7","type":"Environment","parentId":"wrk_ef815fde95ce489aa225fc4408a04bf7","modified":1694436238604,"created":1628147455088,"name":"Base Environment","data":{},"dataPropertyOrder":null,"color":null,"isPrivate":false,"metaSortKey":1628147455088}
|
||||
{"_id":"env_ae8fb881d7f14abbb60c27c82dcf6072","type":"Environment","parentId":"env_727e68a0650a9198b46e09fe922ebdf2c4b14ee9","modified":1694436005646,"created":1694435987858,"name":"Mars","data":{"planet":"mars"},"dataPropertyOrder":{"&":["planet"]},"color":null,"isPrivate":false,"metaSortKey":1694435987858}
|
||||
{"_id":"env_b289a3371fe1228038a8a1df06cc2d0934f6b4f3","type":"Environment","parentId":"wrk_55a8240d025044d3a40eb40956126bec","modified":1694513468817,"created":1694513468817,"name":"Base Environment","data":{},"dataPropertyOrder":null,"color":null,"isPrivate":false,"metaSortKey":1694513468817}
|
||||
{"_id":"env_ce5c6ddfabc8dac33df7b4d14509356c9d280eb8","type":"Environment","parentId":"wrk_7c9f917b97cb4a43bb402ace6df1b107","modified":1694513835049,"created":1694513835049,"name":"Base Environment","data":{},"dataPropertyOrder":null,"color":null,"isPrivate":false,"metaSortKey":1694513835050}
|
||||
{"_id":"env_dfc984a037a5edccac6000064716590ad1628ad9","type":"Environment","parentId":"wrk_d783eca2fa46457c9f02a221ec862458","modified":1694513890780,"created":1694513890780,"name":"Base Environment","data":{},"dataPropertyOrder":null,"color":null,"isPrivate":false,"metaSortKey":1694513890780}
|
||||
{"_id":"env_e123dd1aa0b14e27b25f162787fa90d6","type":"Environment","parentId":"env_284ec449cf894ffd958b9b54ad598c02","modified":1694513741464,"created":1694513741464,"name":"OpenAPI env petstore.swagger.io","data":{"scheme":"https","base_path":"/v2","host":"petstore.swagger.io"},"dataPropertyOrder":null,"color":null,"isPrivate":false,"metaSortKey":1694513478190}
|
||||
@@ -0,0 +1,4 @@
|
||||
{"_id":"git_1fded700bfb74aa483560e116866d25e","type":"GitRepository","parentId":null,"modified":1694436298203,"created":1694436297415,"needsFullClone":false,"uri":"https://github.com/gatzjames/insomnia-git-example.git","credentials":{"username":"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","token":"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","oauth2format":"github"},"author":{"name":"gatzjames","email":"jamesgatzos@gmail.com"},"uriNeedsMigration":false}
|
||||
{"_id":"git_82bf4ce708514ba4a61e5a23a644e0d7","type":"GitRepository","parentId":null,"modified":1694513652868,"created":1694513651705,"needsFullClone":false,"uri":"https://github.com/gatzjames/insomnia-git-example.git","credentials":{"username":"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","token":"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","oauth2format":"github"},"author":{"name":"gatzjames","email":"jamesgatzos@gmail.com"},"uriNeedsMigration":false}
|
||||
{"_id":"git_a02b558275414a518e6107c3e85e405a","type":"GitRepository","parentId":null,"modified":1694513701781,"created":1694513700687,"needsFullClone":false,"uri":"https://github.com/gatzjames/insomnia-git-example.git","credentials":{"username":"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","token":"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","oauth2format":"github"},"author":{"name":"gatzjames","email":"jamesgatzos@gmail.com"},"uriNeedsMigration":false}
|
||||
{"_id":"git_da0217efdd80460faa2f153c1e871083","type":"GitRepository","parentId":null,"modified":1694513852485,"created":1694513851549,"needsFullClone":false,"uri":"https://github.com/gatzjames/insomnia-git-example.git","credentials":{"username":"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","token":"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","oauth2format":"github"},"author":{"name":"gatzjames","email":"jamesgatzos@gmail.com"},"uriNeedsMigration":false}
|
||||
Whitespace-only changes.
Whitespace-only changes.
Whitespace-only changes.
Whitespace-only changes.
@@ -0,0 +1,5 @@
|
||||
{"_id":"proj_default-project","type":"Project","parentId":null,"modified":1694435924693,"created":1694435924693,"name":"Insomnia","remoteId":null}
|
||||
{"_id":"proj_f5359773e8b544c2bfeec86c95b978dc","type":"Project","parentId":null,"modified":1694513815752,"created":1694436032201,"name":"Local Project (GIT)","remoteId":null}
|
||||
{"_id":"proj_777cc16ca5f3419fbc262df283d27bdf","type":"Project","parentId":null,"modified":1694513815752,"created":1694436032201,"name":"Local Project","remoteId":null}
|
||||
{"_id":"proj_scratchpad","type":"Project","parentId":null,"modified":1694513815752,"created":1694436032201,"name":"Scratchpad","remoteId":null}
|
||||
{"_id":"proj_team_195a6ce0edb1427eb2e8ba7b986072e4","type":"Project","parentId":null,"modified":1694513929456,"created":1694513929456,"name":"🪄 Legacy Remote Project","remoteId":"team_195a6ce0edb1427eb2e8ba7b986072e4"}
|
||||
Whitespace-only changes.
Whitespace-only changes.
@@ -0,0 +1,59 @@
|
||||
{"_id":"req_074eb9af1eb04f7da98424aff4f80b50","type":"Request","parentId":"fld_f5d684c7cb994f0abddd2af7b2574369","modified":1694513741665,"created":1694513741665,"url":"{{ _.base_url }}/user/login","name":"Logs user into the system","description":"","method":"GET","body":{},"parameters":[{"name":"username","disabled":false,"value":"string"},{"name":"password","disabled":false,"value":"string"}],"headers":[],"authentication":{},"metaSortKey":-1694513478225,"isPrivate":false,"settingStoreCookies":true,"settingSendCookies":true,"settingDisableRenderRequestBody":false,"settingEncodeUrl":true,"settingRebuildPath":true,"settingFollowRedirects":"global"}
|
||||
{"_id":"req_0c44ae04191b4b26af4a1c4231f3ca26","type":"Request","parentId":"fld_41731ba5147d4132b0969fe7e1a1aff3","modified":1694436082789,"created":1694436082789,"url":"{{ _.base_url }}/user/createWithArray","name":"Creates list of users with given input array","description":"","method":"POST","body":{"mimeType":"application/json","text":"[\n {\n \"id\": 0,\n \"username\": \"string\",\n \"firstName\": \"string\",\n \"lastName\": \"string\",\n \"email\": \"string\",\n \"password\": \"string\",\n \"phone\": \"string\",\n \"userStatus\": 0\n }\n]"},"parameters":[],"headers":[{"name":"Content-Type","disabled":false,"value":"application/json"}],"authentication":{},"metaSortKey":-1694436082789,"isPrivate":false,"settingStoreCookies":true,"settingSendCookies":true,"settingDisableRenderRequestBody":false,"settingEncodeUrl":true,"settingRebuildPath":true,"settingFollowRedirects":"global"}
|
||||
{"_id":"req_0d40d2c37e0c4c31af63098803aa6da9","type":"Request","parentId":"fld_cf6d9eae350248a1afac20cce84c80a4","modified":1694513741540,"created":1694513741540,"url":"{{ _.base_url }}/pet/findByTags","name":"Finds Pets by tags","description":"","method":"GET","body":{},"parameters":[{"name":"tags","disabled":false,"value":"string"}],"headers":[],"authentication":{},"metaSortKey":-1694513478202,"isPrivate":false,"settingStoreCookies":true,"settingSendCookies":true,"settingDisableRenderRequestBody":false,"settingEncodeUrl":true,"settingRebuildPath":true,"settingFollowRedirects":"global"}
|
||||
{"_id":"req_13512e54128346f3ab1d67ad0494fa56","type":"Request","parentId":"fld_fd2217f91f9a48b6b60ba1ecdf21ddef","modified":1694513478197,"created":1694513478197,"url":"{{ _.base_url }}/pet","name":"Add a new pet to the store","description":"","method":"POST","body":{"mimeType":"application/json","text":"{\n \"id\": 0,\n \"category\": {\n \"id\": 0,\n \"name\": \"string\"\n },\n \"name\": \"doggie\",\n \"photoUrls\": [\n \"string\"\n ],\n \"tags\": [\n {\n \"id\": 0,\n \"name\": \"string\"\n }\n ],\n \"status\": \"string\"\n}"},"parameters":[],"headers":[{"name":"Content-Type","disabled":false,"value":"application/json"}],"authentication":{},"metaSortKey":-1694513478198,"isPrivate":false,"settingStoreCookies":true,"settingSendCookies":true,"settingDisableRenderRequestBody":false,"settingEncodeUrl":true,"settingRebuildPath":true,"settingFollowRedirects":"global"}
|
||||
{"_id":"req_145f3154cdcf4a77a8c79a848467704a","type":"Request","parentId":"fld_f5d684c7cb994f0abddd2af7b2574369","modified":1694513741679,"created":1694513741679,"url":"{{ _.base_url }}/user/{{ _.username }}","name":"Get user by user name","description":"","method":"GET","body":{},"parameters":[],"headers":[],"authentication":{},"metaSortKey":-1694513478232,"isPrivate":false,"settingStoreCookies":true,"settingSendCookies":true,"settingDisableRenderRequestBody":false,"settingEncodeUrl":true,"settingRebuildPath":true,"settingFollowRedirects":"global"}
|
||||
{"_id":"req_163e848a55f94c8096d53a70d5ca6ef9","type":"Request","parentId":"fld_0dc862678d1b4b62b519d4ebabccf25f","modified":1694436154213,"created":1694436082780,"url":"{{ _.base_url }}/pet/findByStatus","name":"Finds Pets by status","description":"","method":"GET","body":{},"parameters":[{"name":"status","disabled":false,"value":"available"}],"headers":[],"authentication":{},"metaSortKey":-1694436082780,"isPrivate":false,"settingStoreCookies":true,"settingSendCookies":true,"settingDisableRenderRequestBody":false,"settingEncodeUrl":true,"settingRebuildPath":true,"settingFollowRedirects":"global"}
|
||||
{"_id":"req_1727645245ea4a8a9a485d3af1f8d2f3","type":"Request","parentId":"fld_fd2217f91f9a48b6b60ba1ecdf21ddef","modified":1694513478207,"created":1694513478207,"url":"{{ _.base_url }}/pet/{{ _.petId }}","name":"Deletes a pet","description":"","method":"DELETE","body":{},"parameters":[],"headers":[{"name":"api_key","disabled":true,"value":"string"}],"authentication":{},"metaSortKey":-1694513478207,"isPrivate":false,"settingStoreCookies":true,"settingSendCookies":true,"settingDisableRenderRequestBody":false,"settingEncodeUrl":true,"settingRebuildPath":true,"settingFollowRedirects":"global"}
|
||||
{"_id":"req_192c75d1b70a47c0bbdb38a2ec592e5d","type":"Request","parentId":"fld_15d587ccb28a4438a0c4c1e42b3aebfe","modified":1694513741600,"created":1694513741600,"url":"{{ _.base_url }}/store/order","name":"Place an order for a pet","description":"","method":"POST","body":{"mimeType":"application/json","text":"{\n \"id\": 0,\n \"petId\": 0,\n \"quantity\": 0,\n \"shipDate\": \"2023-09-12T10:11:18.185Z\",\n \"status\": \"string\",\n \"complete\": true\n}"},"parameters":[],"headers":[{"name":"Content-Type","disabled":false,"value":"application/json"}],"authentication":{},"metaSortKey":-1694513478211,"isPrivate":false,"settingStoreCookies":true,"settingSendCookies":true,"settingDisableRenderRequestBody":false,"settingEncodeUrl":true,"settingRebuildPath":true,"settingFollowRedirects":"global"}
|
||||
{"_id":"req_1ca5010386a74c19ad9606d4258998fa","type":"Request","parentId":"fld_cf6d9eae350248a1afac20cce84c80a4","modified":1694513741524,"created":1694513741524,"url":"{{ _.base_url }}/pet","name":"Update an existing pet","description":"","method":"PUT","body":{"mimeType":"application/json","text":"{\n \"id\": 0,\n \"category\": {\n \"id\": 0,\n \"name\": \"string\"\n },\n \"name\": \"doggie\",\n \"photoUrls\": [\n \"string\"\n ],\n \"tags\": [\n {\n \"id\": 0,\n \"name\": \"string\"\n }\n ],\n \"status\": \"string\"\n}"},"parameters":[],"headers":[{"name":"Content-Type","disabled":false,"value":"application/json"}],"authentication":{},"metaSortKey":-1694513478200,"isPrivate":false,"settingStoreCookies":true,"settingSendCookies":true,"settingDisableRenderRequestBody":false,"settingEncodeUrl":true,"settingRebuildPath":true,"settingFollowRedirects":"global"}
|
||||
{"_id":"req_21d2291e0e944359bc57db4d4fb900bc","type":"Request","parentId":"fld_f5d684c7cb994f0abddd2af7b2574369","modified":1694513741673,"created":1694513741673,"url":"{{ _.base_url }}/user/logout","name":"Logs out current logged in user session","description":"","method":"GET","body":{},"parameters":[],"headers":[],"authentication":{},"metaSortKey":-1694513478229,"isPrivate":false,"settingStoreCookies":true,"settingSendCookies":true,"settingDisableRenderRequestBody":false,"settingEncodeUrl":true,"settingRebuildPath":true,"settingFollowRedirects":"global"}
|
||||
{"_id":"req_2b30b68997304e1ab09fdbe2d3cc3767","type":"Request","parentId":"fld_0dc862678d1b4b62b519d4ebabccf25f","modified":1694436082781,"created":1694436082781,"url":"{{ _.base_url }}/pet/findByTags","name":"Finds Pets by tags","description":"","method":"GET","body":{},"parameters":[{"name":"tags","disabled":false,"value":"string"}],"headers":[],"authentication":{},"metaSortKey":-1694436082781,"isPrivate":false,"settingStoreCookies":true,"settingSendCookies":true,"settingDisableRenderRequestBody":false,"settingEncodeUrl":true,"settingRebuildPath":true,"settingFollowRedirects":"global"}
|
||||
{"_id":"req_2b8a18c434654b2cb7b7d1a7d5000fdf","type":"Request","parentId":"fld_15d587ccb28a4438a0c4c1e42b3aebfe","modified":1694513741593,"created":1694513741593,"url":"{{ _.base_url }}/store/inventory","name":"Returns pet inventories by status","description":"","method":"GET","body":{},"parameters":[],"headers":[],"authentication":{},"metaSortKey":-1694513478208,"isPrivate":false,"settingStoreCookies":true,"settingSendCookies":true,"settingDisableRenderRequestBody":false,"settingEncodeUrl":true,"settingRebuildPath":true,"settingFollowRedirects":"global"}
|
||||
{"_id":"req_2c5dc56e4f2c438a89dbb8f7f74ed345","type":"Request","parentId":"fld_cf6d9eae350248a1afac20cce84c80a4","modified":1694513741565,"created":1694513741565,"url":"{{ _.base_url }}/pet/{{ _.petId }}","name":"Deletes a pet","description":"","method":"DELETE","body":{},"parameters":[],"headers":[{"name":"api_key","disabled":true,"value":"string"}],"authentication":{},"metaSortKey":-1694513478207,"isPrivate":false,"settingStoreCookies":true,"settingSendCookies":true,"settingDisableRenderRequestBody":false,"settingEncodeUrl":true,"settingRebuildPath":true,"settingFollowRedirects":"global"}
|
||||
{"_id":"req_3049c3a7c24245c986b29e80ad5a44c6","type":"Request","parentId":"wrk_f3246c005c9d48ed9e35724415c962d6","modified":1694435970569,"created":1694435946705,"url":"https://mockbin.org/status/200","name":"Get list of rockets","description":"","method":"GET","body":{},"parameters":[],"headers":[{"name":"User-Agent","value":"insomnia/2023.5.8"}],"authentication":{},"metaSortKey":-1694435946705,"isPrivate":false,"settingStoreCookies":true,"settingSendCookies":true,"settingDisableRenderRequestBody":false,"settingEncodeUrl":true,"settingRebuildPath":true,"settingFollowRedirects":"global"}
|
||||
{"_id":"req_32194eff4bfb4fa097d9a390eff6a775","type":"Request","parentId":"fld_f5d684c7cb994f0abddd2af7b2574369","modified":1694513741684,"created":1694513741684,"url":"{{ _.base_url }}/user/{{ _.username }}","name":"Updated user","description":"","method":"PUT","body":{"mimeType":"application/json","text":"{\n \"id\": 0,\n \"username\": \"string\",\n \"firstName\": \"string\",\n \"lastName\": \"string\",\n \"email\": \"string\",\n \"password\": \"string\",\n \"phone\": \"string\",\n \"userStatus\": 0\n}"},"parameters":[],"headers":[{"name":"Content-Type","disabled":false,"value":"application/json"}],"authentication":{},"metaSortKey":-1694513478234,"isPrivate":false,"settingStoreCookies":true,"settingSendCookies":true,"settingDisableRenderRequestBody":false,"settingEncodeUrl":true,"settingRebuildPath":true,"settingFollowRedirects":"global"}
|
||||
{"_id":"req_35eb88c4741948cbae6e9067d19b2f32","type":"Request","parentId":"fld_41731ba5147d4132b0969fe7e1a1aff3","modified":1694436082790,"created":1694436082790,"url":"{{ _.base_url }}/user/createWithList","name":"Creates list of users with given input array","description":"","method":"POST","body":{"mimeType":"application/json","text":"[\n {\n \"id\": 0,\n \"username\": \"string\",\n \"firstName\": \"string\",\n \"lastName\": \"string\",\n \"email\": \"string\",\n \"password\": \"string\",\n \"phone\": \"string\",\n \"userStatus\": 0\n }\n]"},"parameters":[],"headers":[{"name":"Content-Type","disabled":false,"value":"application/json"}],"authentication":{},"metaSortKey":-1694436082790,"isPrivate":false,"settingStoreCookies":true,"settingSendCookies":true,"settingDisableRenderRequestBody":false,"settingEncodeUrl":true,"settingRebuildPath":true,"settingFollowRedirects":"global"}
|
||||
{"_id":"req_3b4ca2e394bb486ab0242ddf03035d38","type":"Request","parentId":"fld_41731ba5147d4132b0969fe7e1a1aff3","modified":1694436082788,"created":1694436082788,"url":"{{ _.base_url }}/user","name":"Create user","description":"","method":"POST","body":{"mimeType":"application/json","text":"{\n \"id\": 0,\n \"username\": \"string\",\n \"firstName\": \"string\",\n \"lastName\": \"string\",\n \"email\": \"string\",\n \"password\": \"string\",\n \"phone\": \"string\",\n \"userStatus\": 0\n}"},"parameters":[],"headers":[{"name":"Content-Type","disabled":false,"value":"application/json"}],"authentication":{},"metaSortKey":-1694436082788,"isPrivate":false,"settingStoreCookies":true,"settingSendCookies":true,"settingDisableRenderRequestBody":false,"settingEncodeUrl":true,"settingRebuildPath":true,"settingFollowRedirects":"global"}
|
||||
{"_id":"req_40504764445b424b9931d242d568a067","type":"Request","parentId":"fld_0dc862678d1b4b62b519d4ebabccf25f","modified":1694436082784,"created":1694436082784,"url":"{{ _.base_url }}/pet/{{ _.petId }}","name":"Deletes a pet","description":"","method":"DELETE","body":{},"parameters":[],"headers":[{"name":"api_key","disabled":true,"value":"string"}],"authentication":{},"metaSortKey":-1694436082784,"isPrivate":false,"settingStoreCookies":true,"settingSendCookies":true,"settingDisableRenderRequestBody":false,"settingEncodeUrl":true,"settingRebuildPath":true,"settingFollowRedirects":"global"}
|
||||
{"_id":"req_42f11c00991b4d5890af3f8b751f6842","type":"Request","parentId":"fld_e665ff77102645bf888faaa3af3287a9","modified":1694513478215,"created":1694513478215,"url":"{{ _.base_url }}/store/order/{{ _.orderId }}","name":"Find purchase order by ID","description":"","method":"GET","body":{},"parameters":[],"headers":[],"authentication":{},"metaSortKey":-1694513478215,"isPrivate":false,"settingStoreCookies":true,"settingSendCookies":true,"settingDisableRenderRequestBody":false,"settingEncodeUrl":true,"settingRebuildPath":true,"settingFollowRedirects":"global"}
|
||||
{"_id":"req_45a81258cef8479cbf112d14c44b1da3","type":"Request","parentId":"fld_b6964b1458c749e490815c94816c4ed9","modified":1694436082786,"created":1694436082786,"url":"{{ _.base_url }}/store/order/{{ _.orderId }}","name":"Find purchase order by ID","description":"","method":"GET","body":{},"parameters":[],"headers":[],"authentication":{},"metaSortKey":-1694436082786,"isPrivate":false,"settingStoreCookies":true,"settingSendCookies":true,"settingDisableRenderRequestBody":false,"settingEncodeUrl":true,"settingRebuildPath":true,"settingFollowRedirects":"global"}
|
||||
{"_id":"req_48b9de3ca2f941798e5da7ffadbdd6bd","type":"Request","parentId":"fld_17cc4f5762c5423592d1a384461adf18","modified":1694513478235,"created":1694513478235,"url":"{{ _.base_url }}/user/{{ _.username }}","name":"Delete user","description":"","method":"DELETE","body":{},"parameters":[],"headers":[],"authentication":{},"metaSortKey":-1694513478235,"isPrivate":false,"settingStoreCookies":true,"settingSendCookies":true,"settingDisableRenderRequestBody":false,"settingEncodeUrl":true,"settingRebuildPath":true,"settingFollowRedirects":"global"}
|
||||
{"_id":"req_4fc95d07f7704bed9dc78bb845ef76e1","type":"Request","parentId":"fld_15d587ccb28a4438a0c4c1e42b3aebfe","modified":1694513741616,"created":1694513741616,"url":"{{ _.base_url }}/store/order/{{ _.orderId }}","name":"Find purchase order by ID","description":"","method":"GET","body":{},"parameters":[],"headers":[],"authentication":{},"metaSortKey":-1694513478215,"isPrivate":false,"settingStoreCookies":true,"settingSendCookies":true,"settingDisableRenderRequestBody":false,"settingEncodeUrl":true,"settingRebuildPath":true,"settingFollowRedirects":"global"}
|
||||
{"_id":"req_4ffad86de65a4388bdba565cabacee1a","type":"Request","parentId":"fld_0dc862678d1b4b62b519d4ebabccf25f","modified":1694436082782,"created":1694436082782,"url":"{{ _.base_url }}/pet/{{ _.petId }}","name":"Find pet by ID","description":"","method":"GET","body":{},"parameters":[],"headers":[],"authentication":{},"metaSortKey":-1694436082782,"isPrivate":false,"settingStoreCookies":true,"settingSendCookies":true,"settingDisableRenderRequestBody":false,"settingEncodeUrl":true,"settingRebuildPath":true,"settingFollowRedirects":"global"}
|
||||
{"_id":"req_529632695f3e479bbe9229ae2f63c32c","type":"Request","parentId":"fld_15d587ccb28a4438a0c4c1e42b3aebfe","modified":1694513741625,"created":1694513741625,"url":"{{ _.base_url }}/store/order/{{ _.orderId }}","name":"Delete purchase order by ID","description":"","method":"DELETE","body":{},"parameters":[],"headers":[],"authentication":{},"metaSortKey":-1694513478217,"isPrivate":false,"settingStoreCookies":true,"settingSendCookies":true,"settingDisableRenderRequestBody":false,"settingEncodeUrl":true,"settingRebuildPath":true,"settingFollowRedirects":"global"}
|
||||
{"_id":"req_5d0f087267a342e1800541654b4ee895","type":"Request","parentId":"fld_f5d684c7cb994f0abddd2af7b2574369","modified":1694513741636,"created":1694513741636,"url":"{{ _.base_url }}/user","name":"Create user","description":"","method":"POST","body":{"mimeType":"application/json","text":"{\n \"id\": 0,\n \"username\": \"string\",\n \"firstName\": \"string\",\n \"lastName\": \"string\",\n \"email\": \"string\",\n \"password\": \"string\",\n \"phone\": \"string\",\n \"userStatus\": 0\n}"},"parameters":[],"headers":[{"name":"Content-Type","disabled":false,"value":"application/json"}],"authentication":{},"metaSortKey":-1694513478219,"isPrivate":false,"settingStoreCookies":true,"settingSendCookies":true,"settingDisableRenderRequestBody":false,"settingEncodeUrl":true,"settingRebuildPath":true,"settingFollowRedirects":"global"}
|
||||
{"_id":"req_6391c7cb69f84ca6bcd88920875cad4c","type":"Request","parentId":"fld_41731ba5147d4132b0969fe7e1a1aff3","modified":1694436082792,"created":1694436082792,"url":"{{ _.base_url }}/user/logout","name":"Logs out current logged in user session","description":"","method":"GET","body":{},"parameters":[],"headers":[],"authentication":{},"metaSortKey":-1694436082792,"isPrivate":false,"settingStoreCookies":true,"settingSendCookies":true,"settingDisableRenderRequestBody":false,"settingEncodeUrl":true,"settingRebuildPath":true,"settingFollowRedirects":"global"}
|
||||
{"_id":"req_6724a9231d6e40278a7f5d270c40617a","type":"Request","parentId":"fld_e665ff77102645bf888faaa3af3287a9","modified":1694513478208,"created":1694513478208,"url":"{{ _.base_url }}/store/inventory","name":"Returns pet inventories by status","description":"","method":"GET","body":{},"parameters":[],"headers":[],"authentication":{},"metaSortKey":-1694513478208,"isPrivate":false,"settingStoreCookies":true,"settingSendCookies":true,"settingDisableRenderRequestBody":false,"settingEncodeUrl":true,"settingRebuildPath":true,"settingFollowRedirects":"global"}
|
||||
{"_id":"req_68172cea6e4942a3b914e5ebf1834bcd","type":"Request","parentId":"fld_fd2217f91f9a48b6b60ba1ecdf21ddef","modified":1694513478205,"created":1694513478205,"url":"{{ _.base_url }}/pet/{{ _.petId }}","name":"Updates a pet in the store with form data","description":"","method":"POST","body":{"mimeType":"application/x-www-form-urlencoded"},"parameters":[],"headers":[{"name":"Content-Type","disabled":false,"value":"application/x-www-form-urlencoded"}],"authentication":{},"metaSortKey":-1694513478205,"isPrivate":false,"settingStoreCookies":true,"settingSendCookies":true,"settingDisableRenderRequestBody":false,"settingEncodeUrl":true,"settingRebuildPath":true,"settingFollowRedirects":"global"}
|
||||
{"_id":"req_6945f2841b8b4daf9f6141d7a06c6d62","type":"Request","parentId":"fld_41731ba5147d4132b0969fe7e1a1aff3","modified":1694436082794,"created":1694436082794,"url":"{{ _.base_url }}/user/{{ _.username }}","name":"Delete user","description":"","method":"DELETE","body":{},"parameters":[],"headers":[],"authentication":{},"metaSortKey":-1694436082794,"isPrivate":false,"settingStoreCookies":true,"settingSendCookies":true,"settingDisableRenderRequestBody":false,"settingEncodeUrl":true,"settingRebuildPath":true,"settingFollowRedirects":"global"}
|
||||
{"_id":"req_74bbe9b9290c4bb991e31277d0ca06ce","type":"Request","parentId":"fld_0dc862678d1b4b62b519d4ebabccf25f","modified":1694436082778,"created":1694436082778,"url":"{{ _.base_url }}/pet","name":"Add a new pet to the store","description":"","method":"POST","body":{"mimeType":"application/json","text":"{\n \"id\": 0,\n \"category\": {\n \"id\": 0,\n \"name\": \"string\"\n },\n \"name\": \"doggie\",\n \"photoUrls\": [\n \"string\"\n ],\n \"tags\": [\n {\n \"id\": 0,\n \"name\": \"string\"\n }\n ],\n \"status\": \"string\"\n}"},"parameters":[],"headers":[{"name":"Content-Type","disabled":false,"value":"application/json"}],"authentication":{},"metaSortKey":-1694436082778,"isPrivate":false,"settingStoreCookies":true,"settingSendCookies":true,"settingDisableRenderRequestBody":false,"settingEncodeUrl":true,"settingRebuildPath":true,"settingFollowRedirects":"global"}
|
||||
{"_id":"req_7885c94ca5444575bf245fe35d99bb2b","type":"Request","parentId":"fld_17cc4f5762c5423592d1a384461adf18","modified":1694513478223,"created":1694513478223,"url":"{{ _.base_url }}/user/createWithList","name":"Creates list of users with given input array","description":"","method":"POST","body":{"mimeType":"application/json","text":"[\n {\n \"id\": 0,\n \"username\": \"string\",\n \"firstName\": \"string\",\n \"lastName\": \"string\",\n \"email\": \"string\",\n \"password\": \"string\",\n \"phone\": \"string\",\n \"userStatus\": 0\n }\n]"},"parameters":[],"headers":[{"name":"Content-Type","disabled":false,"value":"application/json"}],"authentication":{},"metaSortKey":-1694513478223,"isPrivate":false,"settingStoreCookies":true,"settingSendCookies":true,"settingDisableRenderRequestBody":false,"settingEncodeUrl":true,"settingRebuildPath":true,"settingFollowRedirects":"global"}
|
||||
{"_id":"req_7d18e1be691a4b6eb4c048bf2024f42c","type":"Request","parentId":"fld_b6964b1458c749e490815c94816c4ed9","modified":1694436082785,"created":1694436082785,"url":"{{ _.base_url }}/store/order","name":"Place an order for a pet","description":"","method":"POST","body":{"mimeType":"application/json","text":"{\n \"id\": 0,\n \"petId\": 0,\n \"quantity\": 0,\n \"shipDate\": \"2023-09-11T12:41:22.746Z\",\n \"status\": \"string\",\n \"complete\": true\n}"},"parameters":[],"headers":[{"name":"Content-Type","disabled":false,"value":"application/json"}],"authentication":{},"metaSortKey":-1694436082785,"isPrivate":false,"settingStoreCookies":true,"settingSendCookies":true,"settingDisableRenderRequestBody":false,"settingEncodeUrl":true,"settingRebuildPath":true,"settingFollowRedirects":"global"}
|
||||
{"_id":"req_8a19defaeb904531896c36af722b7489","type":"Request","parentId":"fld_41731ba5147d4132b0969fe7e1a1aff3","modified":1694436082793,"created":1694436082793,"url":"{{ _.base_url }}/user/{{ _.username }}","name":"Updated user","description":"","method":"PUT","body":{"mimeType":"application/json","text":"{\n \"id\": 0,\n \"username\": \"string\",\n \"firstName\": \"string\",\n \"lastName\": \"string\",\n \"email\": \"string\",\n \"password\": \"string\",\n \"phone\": \"string\",\n \"userStatus\": 0\n}"},"parameters":[],"headers":[{"name":"Content-Type","disabled":false,"value":"application/json"}],"authentication":{},"metaSortKey":-1694436082793,"isPrivate":false,"settingStoreCookies":true,"settingSendCookies":true,"settingDisableRenderRequestBody":false,"settingEncodeUrl":true,"settingRebuildPath":true,"settingFollowRedirects":"global"}
|
||||
{"_id":"req_8c5f57330ff04979b508bdd88d893ebd","type":"Request","parentId":"fld_cf6d9eae350248a1afac20cce84c80a4","modified":1694513741531,"created":1694513741531,"url":"{{ _.base_url }}/pet/findByStatus","name":"Finds Pets by status","description":"","method":"GET","body":{},"parameters":[{"name":"status","disabled":false,"value":"available"}],"headers":[],"authentication":{},"metaSortKey":-1694513478201,"isPrivate":false,"settingStoreCookies":true,"settingSendCookies":true,"settingDisableRenderRequestBody":false,"settingEncodeUrl":true,"settingRebuildPath":true,"settingFollowRedirects":"global"}
|
||||
{"_id":"req_8f33c838b6d046979d9ceb9b4bece221","type":"Request","parentId":"fld_0dc862678d1b4b62b519d4ebabccf25f","modified":1694436082779,"created":1694436082779,"url":"{{ _.base_url }}/pet","name":"Update an existing pet","description":"","method":"PUT","body":{"mimeType":"application/json","text":"{\n \"id\": 0,\n \"category\": {\n \"id\": 0,\n \"name\": \"string\"\n },\n \"name\": \"doggie\",\n \"photoUrls\": [\n \"string\"\n ],\n \"tags\": [\n {\n \"id\": 0,\n \"name\": \"string\"\n }\n ],\n \"status\": \"string\"\n}"},"parameters":[],"headers":[{"name":"Content-Type","disabled":false,"value":"application/json"}],"authentication":{},"metaSortKey":-1694436082779,"isPrivate":false,"settingStoreCookies":true,"settingSendCookies":true,"settingDisableRenderRequestBody":false,"settingEncodeUrl":true,"settingRebuildPath":true,"settingFollowRedirects":"global"}
|
||||
{"_id":"req_916d759fb4d242b6820d934757004499","type":"Request","parentId":"fld_41731ba5147d4132b0969fe7e1a1aff3","modified":1694436082791,"created":1694436082791,"url":"{{ _.base_url }}/user/login","name":"Logs user into the system","description":"","method":"GET","body":{},"parameters":[{"name":"username","disabled":false,"value":"string"},{"name":"password","disabled":false,"value":"string"}],"headers":[],"authentication":{},"metaSortKey":-1694436082791,"isPrivate":false,"settingStoreCookies":true,"settingSendCookies":true,"settingDisableRenderRequestBody":false,"settingEncodeUrl":true,"settingRebuildPath":true,"settingFollowRedirects":"global"}
|
||||
{"_id":"req_91ff9bd78c0145e1aaddc0c35e8272d7","type":"Request","parentId":"fld_fd2217f91f9a48b6b60ba1ecdf21ddef","modified":1694513478202,"created":1694513478202,"url":"{{ _.base_url }}/pet/findByTags","name":"Finds Pets by tags","description":"","method":"GET","body":{},"parameters":[{"name":"tags","disabled":false,"value":"string"}],"headers":[],"authentication":{},"metaSortKey":-1694513478202,"isPrivate":false,"settingStoreCookies":true,"settingSendCookies":true,"settingDisableRenderRequestBody":false,"settingEncodeUrl":true,"settingRebuildPath":true,"settingFollowRedirects":"global"}
|
||||
{"_id":"req_941bb4c1300444a8b8f5764bf544a720","type":"Request","parentId":"fld_e665ff77102645bf888faaa3af3287a9","modified":1694513478211,"created":1694513478211,"url":"{{ _.base_url }}/store/order","name":"Place an order for a pet","description":"","method":"POST","body":{"mimeType":"application/json","text":"{\n \"id\": 0,\n \"petId\": 0,\n \"quantity\": 0,\n \"shipDate\": \"2023-09-12T10:11:18.185Z\",\n \"status\": \"string\",\n \"complete\": true\n}"},"parameters":[],"headers":[{"name":"Content-Type","disabled":false,"value":"application/json"}],"authentication":{},"metaSortKey":-1694513478211,"isPrivate":false,"settingStoreCookies":true,"settingSendCookies":true,"settingDisableRenderRequestBody":false,"settingEncodeUrl":true,"settingRebuildPath":true,"settingFollowRedirects":"global"}
|
||||
{"_id":"req_99a7c1e90e4845988eabd18e45de05e2","type":"Request","parentId":"fld_17cc4f5762c5423592d1a384461adf18","modified":1694513478232,"created":1694513478232,"url":"{{ _.base_url }}/user/{{ _.username }}","name":"Get user by user name","description":"","method":"GET","body":{},"parameters":[],"headers":[],"authentication":{},"metaSortKey":-1694513478232,"isPrivate":false,"settingStoreCookies":true,"settingSendCookies":true,"settingDisableRenderRequestBody":false,"settingEncodeUrl":true,"settingRebuildPath":true,"settingFollowRedirects":"global"}
|
||||
{"_id":"req_9b14424c0b764e26958fae1f9fd6a908","type":"Request","parentId":"fld_f5d684c7cb994f0abddd2af7b2574369","modified":1694513741693,"created":1694513741693,"url":"{{ _.base_url }}/user/{{ _.username }}","name":"Delete user","description":"","method":"DELETE","body":{},"parameters":[],"headers":[],"authentication":{},"metaSortKey":-1694513478235,"isPrivate":false,"settingStoreCookies":true,"settingSendCookies":true,"settingDisableRenderRequestBody":false,"settingEncodeUrl":true,"settingRebuildPath":true,"settingFollowRedirects":"global"}
|
||||
{"_id":"req_a6619ad15c1c46209e5d3777d2015536","type":"Request","parentId":"fld_b6964b1458c749e490815c94816c4ed9","modified":1694436082785,"created":1694436082785,"url":"{{ _.base_url }}/store/inventory","name":"Returns pet inventories by status","description":"","method":"GET","body":{},"parameters":[],"headers":[],"authentication":{},"metaSortKey":-1694436082785,"isPrivate":false,"settingStoreCookies":true,"settingSendCookies":true,"settingDisableRenderRequestBody":false,"settingEncodeUrl":true,"settingRebuildPath":true,"settingFollowRedirects":"global"}
|
||||
{"_id":"req_ae7eb298851f48379de12ff46bd9d1ad","type":"Request","parentId":"fld_e665ff77102645bf888faaa3af3287a9","modified":1694513478217,"created":1694513478217,"url":"{{ _.base_url }}/store/order/{{ _.orderId }}","name":"Delete purchase order by ID","description":"","method":"DELETE","body":{},"parameters":[],"headers":[],"authentication":{},"metaSortKey":-1694513478217,"isPrivate":false,"settingStoreCookies":true,"settingSendCookies":true,"settingDisableRenderRequestBody":false,"settingEncodeUrl":true,"settingRebuildPath":true,"settingFollowRedirects":"global"}
|
||||
{"_id":"req_b223a210e2b64c42b6ac98afec1e9552","type":"Request","parentId":"fld_fd2217f91f9a48b6b60ba1ecdf21ddef","modified":1694513478200,"created":1694513478200,"url":"{{ _.base_url }}/pet","name":"Update an existing pet","description":"","method":"PUT","body":{"mimeType":"application/json","text":"{\n \"id\": 0,\n \"category\": {\n \"id\": 0,\n \"name\": \"string\"\n },\n \"name\": \"doggie\",\n \"photoUrls\": [\n \"string\"\n ],\n \"tags\": [\n {\n \"id\": 0,\n \"name\": \"string\"\n }\n ],\n \"status\": \"string\"\n}"},"parameters":[],"headers":[{"name":"Content-Type","disabled":false,"value":"application/json"}],"authentication":{},"metaSortKey":-1694513478200,"isPrivate":false,"settingStoreCookies":true,"settingSendCookies":true,"settingDisableRenderRequestBody":false,"settingEncodeUrl":true,"settingRebuildPath":true,"settingFollowRedirects":"global"}
|
||||
{"_id":"req_bc90a18e061a41938f0661ab4fff9a3b","type":"Request","parentId":"fld_b6964b1458c749e490815c94816c4ed9","modified":1694436082787,"created":1694436082787,"url":"{{ _.base_url }}/store/order/{{ _.orderId }}","name":"Delete purchase order by ID","description":"","method":"DELETE","body":{},"parameters":[],"headers":[],"authentication":{},"metaSortKey":-1694436082787,"isPrivate":false,"settingStoreCookies":true,"settingSendCookies":true,"settingDisableRenderRequestBody":false,"settingEncodeUrl":true,"settingRebuildPath":true,"settingFollowRedirects":"global"}
|
||||
{"_id":"req_c81095cc13414914a581b82f24bedf91","type":"Request","parentId":"fld_f5d684c7cb994f0abddd2af7b2574369","modified":1694513741658,"created":1694513741658,"url":"{{ _.base_url }}/user/createWithList","name":"Creates list of users with given input array","description":"","method":"POST","body":{"mimeType":"application/json","text":"[\n {\n \"id\": 0,\n \"username\": \"string\",\n \"firstName\": \"string\",\n \"lastName\": \"string\",\n \"email\": \"string\",\n \"password\": \"string\",\n \"phone\": \"string\",\n \"userStatus\": 0\n }\n]"},"parameters":[],"headers":[{"name":"Content-Type","disabled":false,"value":"application/json"}],"authentication":{},"metaSortKey":-1694513478223,"isPrivate":false,"settingStoreCookies":true,"settingSendCookies":true,"settingDisableRenderRequestBody":false,"settingEncodeUrl":true,"settingRebuildPath":true,"settingFollowRedirects":"global"}
|
||||
{"_id":"req_cbe176232cac4dfc9ac2be7302623f03","type":"Request","parentId":"fld_fd2217f91f9a48b6b60ba1ecdf21ddef","modified":1694513478204,"created":1694513478204,"url":"{{ _.base_url }}/pet/{{ _.petId }}","name":"Find pet by ID","description":"","method":"GET","body":{},"parameters":[],"headers":[],"authentication":{},"metaSortKey":-1694513478204,"isPrivate":false,"settingStoreCookies":true,"settingSendCookies":true,"settingDisableRenderRequestBody":false,"settingEncodeUrl":true,"settingRebuildPath":true,"settingFollowRedirects":"global"}
|
||||
{"_id":"req_d108b051765444faa2ab920f166c8e99","type":"Request","parentId":"fld_f5d684c7cb994f0abddd2af7b2574369","modified":1694513741646,"created":1694513741646,"url":"{{ _.base_url }}/user/createWithArray","name":"Creates list of users with given input array","description":"","method":"POST","body":{"mimeType":"application/json","text":"[\n {\n \"id\": 0,\n \"username\": \"string\",\n \"firstName\": \"string\",\n \"lastName\": \"string\",\n \"email\": \"string\",\n \"password\": \"string\",\n \"phone\": \"string\",\n \"userStatus\": 0\n }\n]"},"parameters":[],"headers":[{"name":"Content-Type","disabled":false,"value":"application/json"}],"authentication":{},"metaSortKey":-1694513478221,"isPrivate":false,"settingStoreCookies":true,"settingSendCookies":true,"settingDisableRenderRequestBody":false,"settingEncodeUrl":true,"settingRebuildPath":true,"settingFollowRedirects":"global"}
|
||||
{"_id":"req_d8314112ea8b494a9d2954949deef6c2","type":"Request","parentId":"fld_17cc4f5762c5423592d1a384461adf18","modified":1694513478229,"created":1694513478229,"url":"{{ _.base_url }}/user/logout","name":"Logs out current logged in user session","description":"","method":"GET","body":{},"parameters":[],"headers":[],"authentication":{},"metaSortKey":-1694513478229,"isPrivate":false,"settingStoreCookies":true,"settingSendCookies":true,"settingDisableRenderRequestBody":false,"settingEncodeUrl":true,"settingRebuildPath":true,"settingFollowRedirects":"global"}
|
||||
{"_id":"req_daa311e962424e52a98e51d5ddb4fa5e","type":"Request","parentId":"fld_17cc4f5762c5423592d1a384461adf18","modified":1694513478234,"created":1694513478234,"url":"{{ _.base_url }}/user/{{ _.username }}","name":"Updated user","description":"","method":"PUT","body":{"mimeType":"application/json","text":"{\n \"id\": 0,\n \"username\": \"string\",\n \"firstName\": \"string\",\n \"lastName\": \"string\",\n \"email\": \"string\",\n \"password\": \"string\",\n \"phone\": \"string\",\n \"userStatus\": 0\n}"},"parameters":[],"headers":[{"name":"Content-Type","disabled":false,"value":"application/json"}],"authentication":{},"metaSortKey":-1694513478234,"isPrivate":false,"settingStoreCookies":true,"settingSendCookies":true,"settingDisableRenderRequestBody":false,"settingEncodeUrl":true,"settingRebuildPath":true,"settingFollowRedirects":"global"}
|
||||
{"_id":"req_dbd2fe72a91946359532fbff416f25d7","type":"Request","parentId":"wrk_ef815fde95ce489aa225fc4408a04bf7","modified":1694436250026,"created":1694436242029,"url":"https://mockbin.org","name":"New Request","description":"","method":"GET","body":{},"parameters":[],"headers":[{"name":"User-Agent","value":"insomnia/2023.5.8"}],"authentication":{},"metaSortKey":-1694436242029,"isPrivate":false,"settingStoreCookies":true,"settingSendCookies":true,"settingDisableRenderRequestBody":false,"settingEncodeUrl":true,"settingRebuildPath":true,"settingFollowRedirects":"global"}
|
||||
{"_id":"req_e66296d2c3b6452fb7a425975e045dcf","type":"Request","parentId":"fld_0dc862678d1b4b62b519d4ebabccf25f","modified":1694436082783,"created":1694436082783,"url":"{{ _.base_url }}/pet/{{ _.petId }}","name":"Updates a pet in the store with form data","description":"","method":"POST","body":{"mimeType":"application/x-www-form-urlencoded"},"parameters":[],"headers":[{"name":"Content-Type","disabled":false,"value":"application/x-www-form-urlencoded"}],"authentication":{},"metaSortKey":-1694436082783,"isPrivate":false,"settingStoreCookies":true,"settingSendCookies":true,"settingDisableRenderRequestBody":false,"settingEncodeUrl":true,"settingRebuildPath":true,"settingFollowRedirects":"global"}
|
||||
{"_id":"req_e6c3e9c0bdb847b6a7049e2bd1b43a23","type":"Request","parentId":"fld_41731ba5147d4132b0969fe7e1a1aff3","modified":1694436082792,"created":1694436082792,"url":"{{ _.base_url }}/user/{{ _.username }}","name":"Get user by user name","description":"","method":"GET","body":{},"parameters":[],"headers":[],"authentication":{},"metaSortKey":-1694436082792,"isPrivate":false,"settingStoreCookies":true,"settingSendCookies":true,"settingDisableRenderRequestBody":false,"settingEncodeUrl":true,"settingRebuildPath":true,"settingFollowRedirects":"global"}
|
||||
{"_id":"req_e70fd54fa9284182a776a067d82c2476","type":"Request","parentId":"fld_17cc4f5762c5423592d1a384461adf18","modified":1694513478225,"created":1694513478225,"url":"{{ _.base_url }}/user/login","name":"Logs user into the system","description":"","method":"GET","body":{},"parameters":[{"name":"username","disabled":false,"value":"string"},{"name":"password","disabled":false,"value":"string"}],"headers":[],"authentication":{},"metaSortKey":-1694513478225,"isPrivate":false,"settingStoreCookies":true,"settingSendCookies":true,"settingDisableRenderRequestBody":false,"settingEncodeUrl":true,"settingRebuildPath":true,"settingFollowRedirects":"global"}
|
||||
{"_id":"req_e75682413e444776a85d228211e38285","type":"Request","parentId":"fld_cf6d9eae350248a1afac20cce84c80a4","modified":1694513741515,"created":1694513741515,"url":"{{ _.base_url }}/pet","name":"Add a new pet to the store","description":"","method":"POST","body":{"mimeType":"application/json","text":"{\n \"id\": 0,\n \"category\": {\n \"id\": 0,\n \"name\": \"string\"\n },\n \"name\": \"doggie\",\n \"photoUrls\": [\n \"string\"\n ],\n \"tags\": [\n {\n \"id\": 0,\n \"name\": \"string\"\n }\n ],\n \"status\": \"string\"\n}"},"parameters":[],"headers":[{"name":"Content-Type","disabled":false,"value":"application/json"}],"authentication":{},"metaSortKey":-1694513478198,"isPrivate":false,"settingStoreCookies":true,"settingSendCookies":true,"settingDisableRenderRequestBody":false,"settingEncodeUrl":true,"settingRebuildPath":true,"settingFollowRedirects":"global"}
|
||||
{"_id":"req_e87d6b3019e44dc797296b6bef80371e","type":"Request","parentId":"fld_17cc4f5762c5423592d1a384461adf18","modified":1694513478221,"created":1694513478221,"url":"{{ _.base_url }}/user/createWithArray","name":"Creates list of users with given input array","description":"","method":"POST","body":{"mimeType":"application/json","text":"[\n {\n \"id\": 0,\n \"username\": \"string\",\n \"firstName\": \"string\",\n \"lastName\": \"string\",\n \"email\": \"string\",\n \"password\": \"string\",\n \"phone\": \"string\",\n \"userStatus\": 0\n }\n]"},"parameters":[],"headers":[{"name":"Content-Type","disabled":false,"value":"application/json"}],"authentication":{},"metaSortKey":-1694513478221,"isPrivate":false,"settingStoreCookies":true,"settingSendCookies":true,"settingDisableRenderRequestBody":false,"settingEncodeUrl":true,"settingRebuildPath":true,"settingFollowRedirects":"global"}
|
||||
{"_id":"req_e972c7bc07bc42f7862b4d0888bbb7b5","type":"Request","parentId":"fld_cf6d9eae350248a1afac20cce84c80a4","modified":1694513741546,"created":1694513741546,"url":"{{ _.base_url }}/pet/{{ _.petId }}","name":"Find pet by ID","description":"","method":"GET","body":{},"parameters":[],"headers":[],"authentication":{},"metaSortKey":-1694513478204,"isPrivate":false,"settingStoreCookies":true,"settingSendCookies":true,"settingDisableRenderRequestBody":false,"settingEncodeUrl":true,"settingRebuildPath":true,"settingFollowRedirects":"global"}
|
||||
{"_id":"req_f2a1313381bf471cb3e4e4d95bd67c9f","type":"Request","parentId":"fld_17cc4f5762c5423592d1a384461adf18","modified":1694513478219,"created":1694513478219,"url":"{{ _.base_url }}/user","name":"Create user","description":"","method":"POST","body":{"mimeType":"application/json","text":"{\n \"id\": 0,\n \"username\": \"string\",\n \"firstName\": \"string\",\n \"lastName\": \"string\",\n \"email\": \"string\",\n \"password\": \"string\",\n \"phone\": \"string\",\n \"userStatus\": 0\n}"},"parameters":[],"headers":[{"name":"Content-Type","disabled":false,"value":"application/json"}],"authentication":{},"metaSortKey":-1694513478219,"isPrivate":false,"settingStoreCookies":true,"settingSendCookies":true,"settingDisableRenderRequestBody":false,"settingEncodeUrl":true,"settingRebuildPath":true,"settingFollowRedirects":"global"}
|
||||
{"_id":"req_f9f57fb269a04e9d8b810b988ce715d6","type":"Request","parentId":"fld_cf6d9eae350248a1afac20cce84c80a4","modified":1694513741557,"created":1694513741557,"url":"{{ _.base_url }}/pet/{{ _.petId }}","name":"Updates a pet in the store with form data","description":"","method":"POST","body":{"mimeType":"application/x-www-form-urlencoded"},"parameters":[],"headers":[{"name":"Content-Type","disabled":false,"value":"application/x-www-form-urlencoded"}],"authentication":{},"metaSortKey":-1694513478205,"isPrivate":false,"settingStoreCookies":true,"settingSendCookies":true,"settingDisableRenderRequestBody":false,"settingEncodeUrl":true,"settingRebuildPath":true,"settingFollowRedirects":"global"}
|
||||
{"_id":"req_fd68a98e5f2a4a61b7d1552aa083e12a","type":"Request","parentId":"fld_fd2217f91f9a48b6b60ba1ecdf21ddef","modified":1694513478201,"created":1694513478201,"url":"{{ _.base_url }}/pet/findByStatus","name":"Finds Pets by status","description":"","method":"GET","body":{},"parameters":[{"name":"status","disabled":false,"value":"available"}],"headers":[],"authentication":{},"metaSortKey":-1694513478201,"isPrivate":false,"settingStoreCookies":true,"settingSendCookies":true,"settingDisableRenderRequestBody":false,"settingEncodeUrl":true,"settingRebuildPath":true,"settingFollowRedirects":"global"}
|
||||
@@ -0,0 +1,9 @@
|
||||
{"_id":"fld_0dc862678d1b4b62b519d4ebabccf25f","type":"RequestGroup","parentId":"wrk_a528e60334a54420a7b384bae215ad1b","modified":1694436082773,"created":1694436082773,"name":"pet","description":"Everything about your Pets","environment":{},"environmentPropertyOrder":null,"metaSortKey":-1694436082773}
|
||||
{"_id":"fld_15d587ccb28a4438a0c4c1e42b3aebfe","type":"RequestGroup","parentId":"wrk_1b49626a0a9442b7b9474a1f3493bb5d","modified":1694513741584,"created":1694513741584,"name":"store","description":"Access to Petstore orders","environment":{},"environmentPropertyOrder":null,"metaSortKey":-1694513478194}
|
||||
{"_id":"fld_17cc4f5762c5423592d1a384461adf18","type":"RequestGroup","parentId":"wrk_55a8240d025044d3a40eb40956126bec","modified":1694513478196,"created":1694513478196,"name":"user","description":"Operations about user","environment":{},"environmentPropertyOrder":null,"metaSortKey":-1694513478196}
|
||||
{"_id":"fld_41731ba5147d4132b0969fe7e1a1aff3","type":"RequestGroup","parentId":"wrk_a528e60334a54420a7b384bae215ad1b","modified":1694436082777,"created":1694436082777,"name":"user","description":"Operations about user","environment":{},"environmentPropertyOrder":null,"metaSortKey":-1694436082777}
|
||||
{"_id":"fld_b6964b1458c749e490815c94816c4ed9","type":"RequestGroup","parentId":"wrk_a528e60334a54420a7b384bae215ad1b","modified":1694436082775,"created":1694436082775,"name":"store","description":"Access to Petstore orders","environment":{},"environmentPropertyOrder":null,"metaSortKey":-1694436082775}
|
||||
{"_id":"fld_cf6d9eae350248a1afac20cce84c80a4","type":"RequestGroup","parentId":"wrk_1b49626a0a9442b7b9474a1f3493bb5d","modified":1694513741509,"created":1694513741509,"name":"pet","description":"Everything about your Pets","environment":{},"environmentPropertyOrder":null,"metaSortKey":-1694513478192}
|
||||
{"_id":"fld_e665ff77102645bf888faaa3af3287a9","type":"RequestGroup","parentId":"wrk_55a8240d025044d3a40eb40956126bec","modified":1694513478194,"created":1694513478194,"name":"store","description":"Access to Petstore orders","environment":{},"environmentPropertyOrder":null,"metaSortKey":-1694513478194}
|
||||
{"_id":"fld_f5d684c7cb994f0abddd2af7b2574369","type":"RequestGroup","parentId":"wrk_1b49626a0a9442b7b9474a1f3493bb5d","modified":1694513741632,"created":1694513741632,"name":"user","description":"Operations about user","environment":{},"environmentPropertyOrder":null,"metaSortKey":-1694513478196}
|
||||
{"_id":"fld_fd2217f91f9a48b6b60ba1ecdf21ddef","type":"RequestGroup","parentId":"wrk_55a8240d025044d3a40eb40956126bec","modified":1694513478192,"created":1694513478192,"name":"pet","description":"Everything about your Pets","environment":{},"environmentPropertyOrder":null,"metaSortKey":-1694513478192}
|
||||
Whitespace-only changes.
@@ -0,0 +1,3 @@
|
||||
{"_id":"reqm_3d151304a57144e7aec52dfe22227fcb","type":"RequestMeta","parentId":"req_3049c3a7c24245c986b29e80ad5a44c6","modified":1694513621353,"created":1694435946729,"previewMode":"friendly","responseFilter":"","responseFilterHistory":[],"activeResponseId":"res_12166e333b4245d58f5faa232c348b44","savedRequestBody":{},"pinned":false,"lastActive":1694513621011,"downloadPath":null,"expandedAccordionKeys":{}}
|
||||
{"_id":"reqm_4cad9f930583499cab22d70531d557b6","type":"RequestMeta","parentId":"req_163e848a55f94c8096d53a70d5ca6ef9","modified":1694513822929,"created":1694436132724,"previewMode":"friendly","responseFilter":"","responseFilterHistory":[],"activeResponseId":null,"savedRequestBody":{},"pinned":false,"lastActive":1694513822927,"downloadPath":null,"expandedAccordionKeys":{}}
|
||||
{"_id":"reqm_f7d5118cb91d42d1a50f2a78c781f6bc","type":"RequestMeta","parentId":"req_dbd2fe72a91946359532fbff416f25d7","modified":1694513669923,"created":1694436242051,"previewMode":"friendly","responseFilter":"","responseFilterHistory":[],"activeResponseId":"res_bdef9b7f52ba4c91adfd0bd863c70156","savedRequestBody":{},"pinned":false,"lastActive":1694513669922,"downloadPath":null,"expandedAccordionKeys":{}}
|
||||
@@ -0,0 +1,2 @@
|
||||
{"_id":"rvr_7ff1fa7e4fe64dabbf1d9ba5ba56c79b","type":"RequestVersion","parentId":"req_dbd2fe72a91946359532fbff416f25d7","modified":1694436253725,"created":1694436253725,"compressedRequest":"H4sIAAAAAAAAE21QyU7DMBD9FeRzaFPXCU1u7EJICBU4IVRN4nFj1bWLPaFCVf+dCYtYxHHmzdtmJxZWi1pEfF7oRkuDRxKqSaXKaVEVU2kaY9SkNLLQRyIT9LpBvp7jc4+JeLGBiJ6uBoltXC3QzCaF0VgVLapZBSBlYVql8hnkqjGDxDpoaywyY1JWSk1LWeS5LDPRRgT6uVcyl1Um+uhYvSPapHo8Xod21Vg/CnHJYh7WQ54b3B58Z9KY2mg3ZINnbLBE6sIQ8fL8nscm6FdR7/bv6VmAMCZRPz5lokPQH8PuS/ohYTw8XnJJZr6A64el9SmsvYUxJ5yOitFM7JkNPXV8Z1v4sB4cWB3uQqRrZMvDP81suo32hUuL2oBLmImERNYv7yhEPA1hZZHDUOx/QOj1/8iZTdA4nPMBxs9vnLxX/S1+7tug8WH46i/+HJveOn0L1P1BLoJzYTtHbSO2xL5i6UIDTuzfAN32OFE/AgAA"}
|
||||
{"_id":"rvr_b9e82de8e4df44a8bfc98cce22e4937d","type":"RequestVersion","parentId":"req_3049c3a7c24245c986b29e80ad5a44c6","modified":1694435971248,"created":1694435971248,"compressedRequest":"H4sIAAAAAAAAE21Ry07rMBD9lcrr0IbESZvsuPdyEWKDCqwQqib2tBnVtYs9AaGq/86EhwSIpec85pzxQa3IqlZFfFyVuW5MCXNT6EJXplnUXdHgIgdbgdamVpnilz0Ke4mPAyaWwR4ier4cLZ7jdrUuC12bPBe11Qu0DZbVvND6VAZ1YUeLXbC0JhTFad1oXVbNPK/qJlMmIvDXua4FydQQnbj3zPvUzma7YLYd+WmIm1li4CHNijwXXw+7MdoF8sRR4klYT6JwkZOAFpOJtGcKXjhjCuQ+jKkvzm/l2QX7otrD8a2QGDHGpNr7h0z1CPb9cfhccZcwnpxtpLcon8AN45B8CjtPIGmKclpNF+ooahi4Fx4ZeF89bhB3uAmRr1BWnvwoS+k60pPcQbVrcAkzlZCZ/OaGQ8S/IWwJJQzH4QuE3v6O/KMEncOlEDB+fNqft6rfzc+9CRbvxkN/0y+xG8jZa+D+B/I/OBeel2gpopETt2rjQgdOHV8B1feGK1ICAAA="}
|
||||
@@ -0,0 +1,2 @@
|
||||
{"_id":"res_12166e333b4245d58f5faa232c348b44","type":"Response","parentId":"req_3049c3a7c24245c986b29e80ad5a44c6","modified":1694435971253,"created":1694435971253,"statusCode":200,"statusMessage":"","httpVersion":"HTTP/2","contentType":"application/json; charset=utf-8","url":"https://mockbin.org/status/200","bytesRead":38,"bytesContent":38,"elapsedTime":381.818,"headers":[{"name":"date","value":"Mon, 11 Sep 2023 12:39:33 GMT"},{"name":"content-type","value":"application/json; charset=utf-8"},{"name":"content-length","value":"38"},{"name":"access-control-allow-origin","value":"*"},{"name":"access-control-allow-methods","value":"GET"},{"name":"access-control-allow-headers","value":"host,connection,accept-encoding,x-forwarded-for,cf-ray,x-forwarded-proto,cf-visitor,user-agent,accept,cdn-loop,cf-connecting-ip,x-request-id,x-forwarded-port,via,connect-time,x-request-start,total-route-time"},{"name":"access-control-allow-credentials","value":"true"},{"name":"x-powered-by","value":"mockbin"},{"name":"vary","value":"Accept, Accept-Encoding"},{"name":"etag","value":"W/\"26-tc4xT7f7mVsEKKLOEWnIg/voxtc\""},{"name":"via","value":"1.1 vegur"},{"name":"cf-cache-status","value":"DYNAMIC"},{"name":"report-to","value":"{\"endpoints\":[{\"url\":\"https:\\/\\/a.nel.cloudflare.com\\/report\\/v3?s=miPfsyiWpJm9tu2MW7LXgMXvGoMBjgoWrTYaiyni%2FNe%2FhLrnMUMggweKHreYvw3Wdb97m3q1EO1aIq64p0BJVdhiJEEqRvTvYIQADjKPO3wF92BZNnWrP1hZNgDOeQ%3D%3D\"}],\"group\":\"cf-nel\",\"max_age\":604800}"},{"name":"nel","value":"{\"success_fraction\":0,\"report_to\":\"cf-nel\",\"max_age\":604800}"},{"name":"server","value":"cloudflare"},{"name":"cf-ray","value":"804ff960ffcf0a69-AMS"},{"name":"alt-svc","value":"h3=\":443\"; ma=86400"}],"timelinePath":"/Users/jamesgatz/Library/Application Support/Insomnia/responses/caa4e99f-3aec-418c-a6b8-e235cb9cf100.timeline","bodyPath":"/Users/jamesgatz/Library/Application Support/Insomnia/responses/bb1d4190-8057-4812-b9db-e3073031242d.response","bodyCompression":null,"error":"","requestVersionId":"rvr_b9e82de8e4df44a8bfc98cce22e4937d","settingStoreCookies":true,"settingSendCookies":true,"environmentId":null}
|
||||
{"_id":"res_bdef9b7f52ba4c91adfd0bd863c70156","type":"Response","parentId":"req_dbd2fe72a91946359532fbff416f25d7","modified":1694436253730,"created":1694436253730,"statusCode":200,"statusMessage":"","httpVersion":"HTTP/2","contentType":"text/html; charset=utf-8","url":"https://mockbin.org/","bytesRead":10696,"bytesContent":10696,"elapsedTime":326.637,"headers":[{"name":"date","value":"Mon, 11 Sep 2023 12:44:15 GMT"},{"name":"content-type","value":"text/html; charset=utf-8"},{"name":"vary","value":"Accept-Encoding"},{"name":"via","value":"1.1 vegur"},{"name":"cf-cache-status","value":"DYNAMIC"},{"name":"report-to","value":"{\"endpoints\":[{\"url\":\"https:\\/\\/a.nel.cloudflare.com\\/report\\/v3?s=%2FQ93Z%2FUYZDusNDucRzBELssFpK1QckLl728ZkJ%2Fo%2BYuPeBIsT1nhFp6gRkKglylrjA3YgknADybNMr9Cf2moPv%2B8hw%2F80QO0vxVQTTKJlUS9DZSCcK5aUGO9b1X4gQ%3D%3D\"}],\"group\":\"cf-nel\",\"max_age\":604800}"},{"name":"nel","value":"{\"success_fraction\":0,\"report_to\":\"cf-nel\",\"max_age\":604800}"},{"name":"server","value":"cloudflare"},{"name":"cf-ray","value":"805000467d910a6c-AMS"},{"name":"alt-svc","value":"h3=\":443\"; ma=86400"}],"timelinePath":"/Users/jamesgatz/Library/Application Support/Insomnia/responses/4551ecf6-4d74-4aae-958a-a9b1b4e5cde0.timeline","bodyPath":"/Users/jamesgatz/Library/Application Support/Insomnia/responses/f34e1b3d-cba5-43de-be7a-3a699ffbde1c.response","bodyCompression":null,"error":"","requestVersionId":"rvr_7ff1fa7e4fe64dabbf1d9ba5ba56c79b","settingStoreCookies":true,"settingSendCookies":true,"environmentId":null}
|
||||
File diff suppressed because one or more lines are too long.
@@ -0,0 +1,2 @@
|
||||
{"_id":"sta_75eb607a69ce4fdba7c4056c9e56201d","type":"Stats","parentId":null,"modified":1694513922516,"created":1694435923608,"currentLaunch":1694513410381,"lastLaunch":1694503948477,"currentVersion":"2023.5.8","lastVersion":"2023.5.8","launches":5,"createdRequests":21,"deletedRequests":68,"executedRequests":6}
|
||||
{"_id":"sta_75eb607a69ce4fdba7c4056c9e56201d","type":"Stats","parentId":null,"modified":1694513953000,"created":1694435923608,"currentLaunch":1694513952999,"lastLaunch":1694513410381,"currentVersion":"2023.5.8","lastVersion":"2023.5.8","launches":6,"createdRequests":21,"deletedRequests":68,"executedRequests":6}
|
||||
@@ -0,0 +1,3 @@
|
||||
{"_id":"ut_3778208cf3054e5fb9ddd5ca639a6271","type":"UnitTest","parentId":"uts_aeb27e8dade847ab89f53cab2c0eafbc","modified":1694436094618,"created":1694436076224,"requestId":"req_163e848a55f94c8096d53a70d5ca6ef9","name":"Returns 200","code":"const response1 = await insomnia.send();\nexpect(response1.status).to.equal(200);"}
|
||||
{"_id":"ut_622a9d9239524358bad3418a35f4e4f7","type":"UnitTest","parentId":"uts_c547332ddcda43ca8e47b489519b170f","modified":1694513487822,"created":1694513487822,"requestId":null,"name":"Returns 200","code":"const response1 = await insomnia.send();\nexpect(response1.status).to.equal(200);"}
|
||||
{"_id":"ut_d7e95a6a18fb4409bce4406ac9ea247f","type":"UnitTest","parentId":"uts_6d26df3191ab46a08fe2e5859754e1cf","modified":1694513741709,"created":1694513741709,"requestId":null,"name":"Returns 200","code":"const response1 = await insomnia.send();\nexpect(response1.status).to.equal(200);"}
|
||||
@@ -0,0 +1,4 @@
|
||||
{"_id":"utr_151e4ecb47784bacbea430c71dc6a90b","type":"UnitTestResult","parentId":"wrk_a528e60334a54420a7b384bae215ad1b","modified":1694436090299,"created":1694436090299,"results":{"stats":{"suites":1,"tests":1,"passes":0,"pending":0,"failures":1,"start":{"$$date":1694436090277},"end":{"$$date":1694436090299},"duration":22},"tests":[{"title":"Returns 200","fullTitle":"My Suite Returns 200","file":"/var/folders/_7/6ms57pwx6899ftqnx4cxcsf80000gn/T/insomnia-testing/0.37939980943090235-test.ts","duration":18,"currentRetry":0,"err":{"stack":"Error: attempted to output null or undefined value\n at file:///Applications/Insomnia.app/Contents/Resources/app.asar/index-f89f6e08.js:90:20151\n at /Applications/Insomnia.app/Contents/Resources/app.asar/node_modules/nunjucks/browser/nunjucks.js:2307:5\n at RawTask.call (/Applications/Insomnia.app/Contents/Resources/app.asar/node_modules/nunjucks/browser/nunjucks.js:4583:19)\n at MutationObserver.flush (/Applications/Insomnia.app/Contents/Resources/app.asar/node_modules/nunjucks/browser/nunjucks.js:4660:29)","message":"attempted to output null or undefined value","path":"url","location":{"line":1,"column":1},"type":"render","reason":"undefined","multiple":[{"path":"url","location":"[object Object]","type":"render","reason":"undefined","multiple":"Error: attempted to output null or undefined value"}]}}],"pending":[],"failures":[{"title":"Returns 200","fullTitle":"My Suite Returns 200","file":"/var/folders/_7/6ms57pwx6899ftqnx4cxcsf80000gn/T/insomnia-testing/0.37939980943090235-test.ts","duration":18,"currentRetry":0,"err":{"stack":"Error: attempted to output null or undefined value\n at file:///Applications/Insomnia.app/Contents/Resources/app.asar/index-f89f6e08.js:90:20151\n at /Applications/Insomnia.app/Contents/Resources/app.asar/node_modules/nunjucks/browser/nunjucks.js:2307:5\n at RawTask.call (/Applications/Insomnia.app/Contents/Resources/app.asar/node_modules/nunjucks/browser/nunjucks.js:4583:19)\n at MutationObserver.flush (/Applications/Insomnia.app/Contents/Resources/app.asar/node_modules/nunjucks/browser/nunjucks.js:4660:29)","message":"attempted to output null or undefined value","path":"url","location":{"line":1,"column":1},"type":"render","reason":"undefined","multiple":[{"path":"url","location":"[object Object]","type":"render","reason":"undefined","multiple":"Error: attempted to output null or undefined value"}]}}],"passes":[]}}
|
||||
{"_id":"utr_257e8a95b57d4ce790d12a47fccb18d9","type":"UnitTestResult","parentId":"wrk_a528e60334a54420a7b384bae215ad1b","modified":1694436095101,"created":1694436095101,"results":{"stats":{"suites":1,"tests":1,"passes":0,"pending":0,"failures":1,"start":{"$$date":1694436095069},"end":{"$$date":1694436095101},"duration":32},"tests":[{"title":"Returns 200","fullTitle":"My Suite Returns 200","file":"/var/folders/_7/6ms57pwx6899ftqnx4cxcsf80000gn/T/insomnia-testing/0.46268860035276904-test.ts","duration":31,"currentRetry":0,"err":{"stack":"Error: attempted to output null or undefined value\n at file:///Applications/Insomnia.app/Contents/Resources/app.asar/index-f89f6e08.js:90:20151\n at /Applications/Insomnia.app/Contents/Resources/app.asar/node_modules/nunjucks/browser/nunjucks.js:2307:5\n at RawTask.call (/Applications/Insomnia.app/Contents/Resources/app.asar/node_modules/nunjucks/browser/nunjucks.js:4583:19)\n at MutationObserver.flush (/Applications/Insomnia.app/Contents/Resources/app.asar/node_modules/nunjucks/browser/nunjucks.js:4660:29)","message":"attempted to output null or undefined value","path":"url","location":{"line":1,"column":1},"type":"render","reason":"undefined","multiple":[{"path":"url","location":"[object Object]","type":"render","reason":"undefined","multiple":"Error: attempted to output null or undefined value"}]}}],"pending":[],"failures":[{"title":"Returns 200","fullTitle":"My Suite Returns 200","file":"/var/folders/_7/6ms57pwx6899ftqnx4cxcsf80000gn/T/insomnia-testing/0.46268860035276904-test.ts","duration":31,"currentRetry":0,"err":{"stack":"Error: attempted to output null or undefined value\n at file:///Applications/Insomnia.app/Contents/Resources/app.asar/index-f89f6e08.js:90:20151\n at /Applications/Insomnia.app/Contents/Resources/app.asar/node_modules/nunjucks/browser/nunjucks.js:2307:5\n at RawTask.call (/Applications/Insomnia.app/Contents/Resources/app.asar/node_modules/nunjucks/browser/nunjucks.js:4583:19)\n at MutationObserver.flush (/Applications/Insomnia.app/Contents/Resources/app.asar/node_modules/nunjucks/browser/nunjucks.js:4660:29)","message":"attempted to output null or undefined value","path":"url","location":{"line":1,"column":1},"type":"render","reason":"undefined","multiple":[{"path":"url","location":"[object Object]","type":"render","reason":"undefined","multiple":"Error: attempted to output null or undefined value"}]}}],"passes":[]}}
|
||||
{"_id":"utr_89249ee8bad14df883d26fc097d77eaf","type":"UnitTestResult","parentId":"wrk_a528e60334a54420a7b384bae215ad1b","modified":1694436101914,"created":1694436101914,"results":{"stats":{"suites":1,"tests":1,"passes":0,"pending":0,"failures":1,"start":{"$$date":1694436101899},"end":{"$$date":1694436101914},"duration":15},"tests":[{"title":"Returns 200","fullTitle":"My Suite Returns 200","file":"/var/folders/_7/6ms57pwx6899ftqnx4cxcsf80000gn/T/insomnia-testing/0.5942253207975523-test.ts","duration":14,"currentRetry":0,"err":{"stack":"Error: attempted to output null or undefined value\n at file:///Applications/Insomnia.app/Contents/Resources/app.asar/index-f89f6e08.js:90:20151\n at /Applications/Insomnia.app/Contents/Resources/app.asar/node_modules/nunjucks/browser/nunjucks.js:2307:5\n at RawTask.call (/Applications/Insomnia.app/Contents/Resources/app.asar/node_modules/nunjucks/browser/nunjucks.js:4583:19)\n at MutationObserver.flush (/Applications/Insomnia.app/Contents/Resources/app.asar/node_modules/nunjucks/browser/nunjucks.js:4660:29)","message":"attempted to output null or undefined value","path":"url","location":{"line":1,"column":1},"type":"render","reason":"undefined","multiple":[{"path":"url","location":"[object Object]","type":"render","reason":"undefined","multiple":"Error: attempted to output null or undefined value"}]}}],"pending":[],"failures":[{"title":"Returns 200","fullTitle":"My Suite Returns 200","file":"/var/folders/_7/6ms57pwx6899ftqnx4cxcsf80000gn/T/insomnia-testing/0.5942253207975523-test.ts","duration":14,"currentRetry":0,"err":{"stack":"Error: attempted to output null or undefined value\n at file:///Applications/Insomnia.app/Contents/Resources/app.asar/index-f89f6e08.js:90:20151\n at /Applications/Insomnia.app/Contents/Resources/app.asar/node_modules/nunjucks/browser/nunjucks.js:2307:5\n at RawTask.call (/Applications/Insomnia.app/Contents/Resources/app.asar/node_modules/nunjucks/browser/nunjucks.js:4583:19)\n at MutationObserver.flush (/Applications/Insomnia.app/Contents/Resources/app.asar/node_modules/nunjucks/browser/nunjucks.js:4660:29)","message":"attempted to output null or undefined value","path":"url","location":{"line":1,"column":1},"type":"render","reason":"undefined","multiple":[{"path":"url","location":"[object Object]","type":"render","reason":"undefined","multiple":"Error: attempted to output null or undefined value"}]}}],"passes":[]}}
|
||||
{"_id":"utr_96caab34bbdd46e8940ab260c53441cd","type":"UnitTestResult","parentId":"wrk_a528e60334a54420a7b384bae215ad1b","modified":1694436103834,"created":1694436103834,"results":{"stats":{"suites":1,"tests":1,"passes":0,"pending":0,"failures":1,"start":{"$$date":1694436103818},"end":{"$$date":1694436103834},"duration":16},"tests":[{"title":"Returns 200","fullTitle":"My Suite Returns 200","file":"/var/folders/_7/6ms57pwx6899ftqnx4cxcsf80000gn/T/insomnia-testing/0.55166761668619-test.ts","duration":14,"currentRetry":0,"err":{"stack":"Error: attempted to output null or undefined value\n at file:///Applications/Insomnia.app/Contents/Resources/app.asar/index-f89f6e08.js:90:20151\n at /Applications/Insomnia.app/Contents/Resources/app.asar/node_modules/nunjucks/browser/nunjucks.js:2307:5\n at RawTask.call (/Applications/Insomnia.app/Contents/Resources/app.asar/node_modules/nunjucks/browser/nunjucks.js:4583:19)\n at MutationObserver.flush (/Applications/Insomnia.app/Contents/Resources/app.asar/node_modules/nunjucks/browser/nunjucks.js:4660:29)","message":"attempted to output null or undefined value","path":"url","location":{"line":1,"column":1},"type":"render","reason":"undefined","multiple":[{"path":"url","location":"[object Object]","type":"render","reason":"undefined","multiple":"Error: attempted to output null or undefined value"}]}}],"pending":[],"failures":[{"title":"Returns 200","fullTitle":"My Suite Returns 200","file":"/var/folders/_7/6ms57pwx6899ftqnx4cxcsf80000gn/T/insomnia-testing/0.55166761668619-test.ts","duration":14,"currentRetry":0,"err":{"stack":"Error: attempted to output null or undefined value\n at file:///Applications/Insomnia.app/Contents/Resources/app.asar/index-f89f6e08.js:90:20151\n at /Applications/Insomnia.app/Contents/Resources/app.asar/node_modules/nunjucks/browser/nunjucks.js:2307:5\n at RawTask.call (/Applications/Insomnia.app/Contents/Resources/app.asar/node_modules/nunjucks/browser/nunjucks.js:4583:19)\n at MutationObserver.flush (/Applications/Insomnia.app/Contents/Resources/app.asar/node_modules/nunjucks/browser/nunjucks.js:4660:29)","message":"attempted to output null or undefined value","path":"url","location":{"line":1,"column":1},"type":"render","reason":"undefined","multiple":[{"path":"url","location":"[object Object]","type":"render","reason":"undefined","multiple":"Error: attempted to output null or undefined value"}]}}],"passes":[]}}
|
||||
@@ -0,0 +1,3 @@
|
||||
{"_id":"uts_6d26df3191ab46a08fe2e5859754e1cf","type":"UnitTestSuite","parentId":"wrk_1b49626a0a9442b7b9474a1f3493bb5d","modified":1694513741703,"created":1694513741703,"name":"New Suite"}
|
||||
{"_id":"uts_aeb27e8dade847ab89f53cab2c0eafbc","type":"UnitTestSuite","parentId":"wrk_a528e60334a54420a7b384bae215ad1b","modified":1694436073148,"created":1694436073148,"name":"Test Open API"}
|
||||
{"_id":"uts_c547332ddcda43ca8e47b489519b170f","type":"UnitTestSuite","parentId":"wrk_55a8240d025044d3a40eb40956126bec","modified":1694513485323,"created":1694513485323,"name":"New Suite"}
|
||||
Whitespace-only changes.
Whitespace-only changes.
Whitespace-only changes.
@@ -0,0 +1,8 @@
|
||||
{"_id":"wrk_1b49626a0a9442b7b9474a1f3493bb5d","type":"Workspace","parentId":"proj_team_195a6ce0edb1427eb2e8ba7b986072e4","modified":1694513770541,"created":1694513741451,"name":"Remote Design Document","description":"","scope":"design"}
|
||||
{"_id":"wrk_3f71ff5dcf5343169b9a67236f9deafe","type":"Workspace","parentId":"proj_team_195a6ce0edb1427eb2e8ba7b986072e4","modified":1694513800004,"created":1694513691424,"name":"(GIT) Remote Collection","description":"","scope":"collection"}
|
||||
{"_id":"wrk_55a8240d025044d3a40eb40956126bec","type":"Workspace","parentId":"proj_team_195a6ce0edb1427eb2e8ba7b986072e4","modified":1694513791914,"created":1694513468782,"name":"(GIT) Remote Design Document","description":"","scope":"design"}
|
||||
{"_id":"wrk_7c9f917b97cb4a43bb402ace6df1b107","type":"Workspace","parentId":"proj_f5359773e8b544c2bfeec86c95b978dc","modified":1694513877548,"created":1694513835041,"name":"Local Collection","description":"","scope":"collection"}
|
||||
{"_id":"wrk_a528e60334a54420a7b384bae215ad1b","type":"Workspace","parentId":"proj_f5359773e8b544c2bfeec86c95b978dc","modified":1694436050037,"created":1694436050037,"name":"OpenAPI","description":"","scope":"design"}
|
||||
{"_id":"wrk_d783eca2fa46457c9f02a221ec862458","type":"Workspace","parentId":"proj_default-project","modified":1694513890770,"created":1694513890770,"name":"Local Design Document","description":"","scope":"design"}
|
||||
{"_id":"wrk_ef815fde95ce489aa225fc4408a04bf7","type":"Workspace","parentId":"proj_team_195a6ce0edb1427eb2e8ba7b986072e4","modified":1694513499173,"created":1628147455076,"name":"Remote Collection","description":"","scope":"collection"}
|
||||
{"_id":"wrk_f3246c005c9d48ed9e35724415c962d6","type":"Workspace","parentId":"proj_default-project","modified":1694513902250,"created":1694435944027,"name":"Local Collection","description":"","scope":"collection"}
|
||||
@@ -0,0 +1,8 @@
|
||||
{"_id":"wrkm_058529e2e6f541d4b58f4beebc0c8dbe","type":"WorkspaceMeta","parentId":"wrk_3f71ff5dcf5343169b9a67236f9deafe","modified":1694513700703,"created":1694513691444,"activeActivity":null,"activeEnvironmentId":null,"activeRequestId":null,"activeUnitTestSuiteId":null,"cachedGitLastAuthor":null,"cachedGitLastCommitTime":null,"cachedGitRepositoryBranch":null,"gitRepositoryId":"git_a02b558275414a518e6107c3e85e405a","hasSeen":true,"paneHeight":0.5,"paneWidth":0.5,"sidebarFilter":"","sidebarHidden":false,"sidebarWidth":19,"pushSnapshotOnInitialize":false}
|
||||
{"_id":"wrkm_13722a5db6a34919b78af1b167674ef0","type":"WorkspaceMeta","parentId":"wrk_1b49626a0a9442b7b9474a1f3493bb5d","modified":1694513743823,"created":1694513741737,"activeActivity":null,"activeEnvironmentId":null,"activeRequestId":null,"activeUnitTestSuiteId":null,"cachedGitLastAuthor":null,"cachedGitLastCommitTime":null,"cachedGitRepositoryBranch":null,"gitRepositoryId":null,"hasSeen":true,"paneHeight":0.5,"paneWidth":0.5,"sidebarFilter":"","sidebarHidden":false,"sidebarWidth":19,"pushSnapshotOnInitialize":false}
|
||||
{"_id":"wrkm_3a87a51a288d428786650a91deeb507e","type":"WorkspaceMeta","parentId":"wrk_f3246c005c9d48ed9e35724415c962d6","modified":1694513620993,"created":1694435944035,"activeActivity":null,"activeEnvironmentId":"env_ae8fb881d7f14abbb60c27c82dcf6072","activeRequestId":"req_3049c3a7c24245c986b29e80ad5a44c6","activeUnitTestSuiteId":null,"cachedGitLastAuthor":null,"cachedGitLastCommitTime":null,"cachedGitRepositoryBranch":null,"gitRepositoryId":null,"hasSeen":true,"paneHeight":0.5,"paneWidth":0.5,"sidebarFilter":"","sidebarHidden":false,"sidebarWidth":19,"pushSnapshotOnInitialize":false}
|
||||
{"_id":"wrkm_6d6bed9b0a464bc2a1fcdf0c1a137538","type":"WorkspaceMeta","parentId":"wrk_55a8240d025044d3a40eb40956126bec","modified":1694513651760,"created":1694513468824,"activeActivity":null,"activeEnvironmentId":null,"activeRequestId":null,"activeUnitTestSuiteId":"uts_c547332ddcda43ca8e47b489519b170f","cachedGitLastAuthor":null,"cachedGitLastCommitTime":null,"cachedGitRepositoryBranch":null,"gitRepositoryId":"git_82bf4ce708514ba4a61e5a23a644e0d7","hasSeen":true,"paneHeight":0.5,"paneWidth":0.5,"sidebarFilter":"","sidebarHidden":false,"sidebarWidth":19,"pushSnapshotOnInitialize":false}
|
||||
{"_id":"wrkm_9675fa52fcb544bd9b9f383ae2bfcc5d","type":"WorkspaceMeta","parentId":"wrk_ef815fde95ce489aa225fc4408a04bf7","modified":1694513669920,"created":1694436238621,"activeActivity":null,"activeEnvironmentId":null,"activeRequestId":"req_dbd2fe72a91946359532fbff416f25d7","activeUnitTestSuiteId":null,"cachedGitLastAuthor":null,"cachedGitLastCommitTime":null,"cachedGitRepositoryBranch":null,"gitRepositoryId":null,"hasSeen":true,"paneHeight":0.5,"paneWidth":0.5,"sidebarFilter":"","sidebarHidden":false,"sidebarWidth":19,"pushSnapshotOnInitialize":false}
|
||||
{"_id":"wrkm_b7225af0fbe347568acadd18904389ee","type":"WorkspaceMeta","parentId":"wrk_7c9f917b97cb4a43bb402ace6df1b107","modified":1694513851556,"created":1694513835065,"activeActivity":null,"activeEnvironmentId":null,"activeRequestId":null,"activeUnitTestSuiteId":null,"cachedGitLastAuthor":null,"cachedGitLastCommitTime":null,"cachedGitRepositoryBranch":null,"gitRepositoryId":"git_da0217efdd80460faa2f153c1e871083","hasSeen":true,"paneHeight":0.5,"paneWidth":0.5,"sidebarFilter":"","sidebarHidden":false,"sidebarWidth":19,"pushSnapshotOnInitialize":false}
|
||||
{"_id":"wrkm_ede333e3b385412fbdce7e4b5e2d1695","type":"WorkspaceMeta","parentId":"wrk_a528e60334a54420a7b384bae215ad1b","modified":1694513822919,"created":1694436050046,"activeActivity":null,"activeEnvironmentId":"env_05e568304a74414b8b19bec3bae0e38d","activeRequestId":"req_163e848a55f94c8096d53a70d5ca6ef9","activeUnitTestSuiteId":"uts_aeb27e8dade847ab89f53cab2c0eafbc","cachedGitLastAuthor":null,"cachedGitLastCommitTime":null,"cachedGitRepositoryBranch":null,"gitRepositoryId":"git_1fded700bfb74aa483560e116866d25e","hasSeen":true,"paneHeight":0.5,"paneWidth":0.5,"sidebarFilter":"","sidebarHidden":false,"sidebarWidth":19,"pushSnapshotOnInitialize":false}
|
||||
{"_id":"wrkm_f305f30c0eea4bfbb81ecbf3f00887e8","type":"WorkspaceMeta","parentId":"wrk_d783eca2fa46457c9f02a221ec862458","modified":1694513890794,"created":1694513890794,"activeActivity":null,"activeEnvironmentId":null,"activeRequestId":null,"activeUnitTestSuiteId":null,"cachedGitLastAuthor":null,"cachedGitLastCommitTime":null,"cachedGitRepositoryBranch":null,"gitRepositoryId":null,"hasSeen":true,"paneHeight":0.5,"paneWidth":0.5,"sidebarFilter":"","sidebarHidden":false,"sidebarWidth":19,"pushSnapshotOnInitialize":false}
|
||||
@@ -20,6 +20,12 @@ const config: PlaywrightTestConfig = {
|
||||
testMatch: /critical\/.*.test.ts/,
|
||||
retries: 0,
|
||||
},
|
||||
{
|
||||
// Single critical path test, runs on release recurring
|
||||
name: 'Migration',
|
||||
testMatch: /migration\/.*.test.ts/,
|
||||
retries: 0,
|
||||
},
|
||||
],
|
||||
webServer: {
|
||||
command: 'npm run serve',
|
||||
|
||||
@@ -12,6 +12,16 @@ export const loadFixture = async (fixturePath: string) => {
|
||||
return buffer.toString('utf-8');
|
||||
};
|
||||
|
||||
export const copyFixtureDatabase = async (fixturePath: string, dataPath: string) => {
|
||||
const fixtureDir = path.join(__dirname, '..', 'fixtures', fixturePath);
|
||||
|
||||
if (!fs.existsSync(fixtureDir)) {
|
||||
throw new Error(`Cannot find fixture directory ${fixtureDir}`);
|
||||
}
|
||||
|
||||
await fs.promises.cp(fixtureDir, dataPath, { recursive: true });
|
||||
};
|
||||
|
||||
export const randomDataPath = () => path.join(os.tmpdir(), 'insomnia-smoke-test', `${uuidv4()}`);
|
||||
export const INSOMNIA_DATA_PATH = randomDataPath();
|
||||
|
||||
|
||||
@@ -14,24 +14,53 @@ interface EnvOptions {
|
||||
INSOMNIA_DATA_PATH: string;
|
||||
INSOMNIA_API_URL: string;
|
||||
INSOMNIA_APP_WEBSITE_URL: string;
|
||||
INSOMNIA_AI_URL: string;
|
||||
INSOMNIA_GITHUB_API_URL: string;
|
||||
INSOMNIA_GITLAB_API_URL: string;
|
||||
INSOMNIA_UPDATES_URL: string;
|
||||
INSOMNIA_SKIP_ONBOARDING: string;
|
||||
INSOMNIA_PUBLIC_KEY: string;
|
||||
INSOMNIA_SECRET_KEY: string;
|
||||
INSOMNIA_SESSION?: string;
|
||||
}
|
||||
|
||||
export const test = baseTest.extend<{
|
||||
app: ElectronApplication;
|
||||
dataPath: string;
|
||||
fixturesPath: string;
|
||||
userConfig: {
|
||||
skipOnboarding: boolean;
|
||||
publicKey: string;
|
||||
secretKey: string;
|
||||
code: string;
|
||||
session?: {
|
||||
accountId: string;
|
||||
id: string;
|
||||
sessionExpiry: Date;
|
||||
email: string;
|
||||
firstName: string;
|
||||
lastName: string;
|
||||
symmetricKey: string;
|
||||
publicKey: string;
|
||||
encPrivateKey: string;
|
||||
};
|
||||
};
|
||||
}>({
|
||||
app: async ({ playwright, trace }, use, testInfo) => {
|
||||
app: async ({ playwright, trace, dataPath, userConfig }, use, testInfo) => {
|
||||
const webServerUrl = testInfo.config.webServer?.url;
|
||||
|
||||
const options: EnvOptions = {
|
||||
INSOMNIA_DATA_PATH: randomDataPath(),
|
||||
INSOMNIA_DATA_PATH: dataPath,
|
||||
INSOMNIA_API_URL: webServerUrl + '/api',
|
||||
INSOMNIA_APP_WEBSITE_URL: webServerUrl + '/website',
|
||||
INSOMNIA_AI_URL: webServerUrl + '/ai',
|
||||
INSOMNIA_GITHUB_API_URL: webServerUrl + '/github-api/graphql',
|
||||
INSOMNIA_GITLAB_API_URL: webServerUrl + '/gitlab-api',
|
||||
INSOMNIA_UPDATES_URL: webServerUrl || 'https://updates.insomnia.rest',
|
||||
INSOMNIA_SKIP_ONBOARDING: String(userConfig.skipOnboarding),
|
||||
INSOMNIA_PUBLIC_KEY: userConfig.publicKey,
|
||||
INSOMNIA_SECRET_KEY: userConfig.secretKey,
|
||||
...userConfig.session ? { INSOMNIA_SESSION: JSON.stringify(userConfig.session) } : {},
|
||||
};
|
||||
|
||||
const electronApp = await playwright._electron.launch({
|
||||
@@ -46,6 +75,7 @@ export const test = baseTest.extend<{
|
||||
});
|
||||
|
||||
const appContext = electronApp.context();
|
||||
|
||||
const traceMode: TraceMode = typeof trace === 'string' ? trace as TraceMode : trace.mode;
|
||||
|
||||
const defaultTraceOptions = { screenshots: true, snapshots: true, sources: true };
|
||||
@@ -73,4 +103,29 @@ export const test = baseTest.extend<{
|
||||
|
||||
await use(page);
|
||||
},
|
||||
dataPath: async ({ }, use) => {
|
||||
const insomniaDataPath = randomDataPath();
|
||||
|
||||
await use(insomniaDataPath);
|
||||
},
|
||||
userConfig: async ({ }, use) => {
|
||||
await use({
|
||||
skipOnboarding: true,
|
||||
publicKey: 'txb/w8DASTpPQqeHE/hpI3ABKzit+pv5n2We5dbtYRo=',
|
||||
secretKey: 'Tb1QKsI3wVZxhS8TuQESHB2x7f68PzeTzTMmLpnnFVU=',
|
||||
code: 'BTxpIfgXY1VgUpoPpqA25RkCPGQ2MAkZsaY6IZ0bamd0WsYQlJM6iy8PV9hEHS1Gk96SBC6%2BM%2FGhv8IaVl1N6V5wdghHwU2sGKGkW%2Fevx1HiqAUsAqIry8aWRqAkc0n3KmW%2B%2F8lyeHCpy5jhsXqMMqXMbZh8dN1q%2ByRe2C6MJS1A706KbPUhI7PRi%2FsmK0TcNT7lgBKKHRVzPTvjpLcjgzSJFL4K%2BEzgY9Ue4gh0gPw89sM9dV%2F2sAlpw0LA7rF06NyoPhA%3D',
|
||||
session: {
|
||||
'id': 'sess_64a477e6b59d43a5a607f84b4f73e3ce',
|
||||
// Expire in 2077
|
||||
'sessionExpiry': new Date(2147483647000),
|
||||
'publicKey': "{ 'alg': 'RSA-OAEP-256', 'e': 'AQAB', 'ext': true, 'key_ops': ['encrypt'], 'kty': 'RSA', 'n': 'pTQVaUaiqggIldSKm6ib6eFRLLoGj9W-2O4gTbiorR-2b8-ZmKUwQ0F-jgYX71AjYaFn5VjOHOHSP6byNAjN7WzJ6A_Z3tytNraLoZfwK8KdfflOCZiZzQeD3nO8BNgh_zEgCHStU61b6N6bSpCKjbyPkmZcOkJfsz0LJMAxrXvFB-I42WYA2vJKReTJKXeYx4d6L_XGNIoYtmGZit8FldT4AucfQUXgdlKvr4_OZmt6hgjwt_Pjcu-_jO7m589mMWMebfUhjte3Lp1jps0MqTOvgRb0FQf5eoBHnL01OZjvFPDKeqlvoz7II9wFNHIKzSvgAKnyemh6DiyPuIukyQ' }",
|
||||
'encPrivateKey': "{ 'iv': '4a09fba2c412d7ea205b6168', 't': 'a4fa1a524e89e668444de654f1bd1ba8', 'd': 'b695b6ec7d41327b723e395b3788cc08c89dcf7b4db0811c3e91af4aa9ed1c9cb8132b591fe24498ffcc48c0055c1c0985a48d9e96962961c049cea508b6c38e83dfc831a4b1a82ad3e79a26d6ed3c1c9b73043a0e266cfe6eac661a75f4b9862afe2a81362d640bb2fdb6d0015204d04c322f1cb7f33faa593b538b58bda75b0c5e56583d5a55eea89e74d96ce29d862614414ee298f56105ea3dbc479aea9330618ba3e94efe874b33cd99954b12f27d7ff9e7f981310381fa0b3f1a05fbac71862ecc67ddbf7062f718d1d8bbf03f35afc3a8b1b36b177f278ab8dd12c14c862bca52a2c63bca05c7fc9bd8f1000ddc328ad1b5a72b96f110c3443294129db416bd385d19c73a1b342b4887feffa17639cc96b7b7154903c2de183f73d3116d98c8d32ea8b9627d0a5200da98d28c89c34008d4e6fa4cfbd7e1b7e1f36cfec6d0020b306c7def8d24c6091252764bde2eef74f35bdaa605dc27fcd302d179fcf65d6c7d18d3dd36cf6380bd40a29198a0398a6cb1ab79a71be00f7783b6559a146f1f825d25a990162e923e2dbfdd1ee868c8b63844f9394415ebab9f397c8d78608de00369728744b8344724e5c2f1e4ba95522406bd7042fc271793af32bfa1c2724defc8a88185cc5c2825c0453fcb39dc5ac9147d3ba60006fccca855678521da06b426dfd04333511b7d8184a8960dadefb1ef89f5fa648304adcd79734fea763f7dbd0c2788c64ea302f8e33602ab041aec619661167b2f167a4b2cadc6b7cf0c22867fcdd73528fb5585b9d13f6d90ab36c5ef231bd4f2464650e541e6dead1753487b45a8ade3fe46e2327fd0e32d8adafd4e1d2ffcb2df1ed50718d0d29829f8bf4bc33da524640388b0cb9f640b70f9ef0a1d073bc80abdf975fe77b35f07aee5135e2924661d26e5d299a432c563a3bbc5ff21d1fde07ff2336b32b17067c01adc6697568aabf3ff4882530763f77d96cef2fcc7336e3f8e4a2b8de5df42aaeaeccd9e3681604e677fad555148ced6057d99cab03389bb566b27cc4ea3946a640f05593e5944c74adf5d0649941b8032dc6959bdef917fd7d2da3139b1d3770d411b52752c9299f789ce5de64e802740a8210e1c70e0ffb8aa45a3647b837e2c5d1a7dd676b238268ac7c060bcc771285f21a283c2f0eefb54254086770a4f09140f7b6a118a7df1e06445379080c2cb6a8840b9d70411521107b47751634e3ff6437974ac2e5897e7e15ac8bdbb5325bb1dd09c20f8ac37fa1eaf2765671fd1434460cbf3cc97bf67b19f88b2bfbde99836c27c338b7f19fc20aad90b91e268c87b81aa17026ac5ac74f47c3525fd2d0d584d3b1d75dd360f105f78b2831481802b6a40e88938660d1598947ffb4e7cf75cd67308d6f910be2fb9beafb68d5ea7c3d2f79c3b66223d610a70a6f9ce3c3447bc0acf74e84687c2da5a137b6c14631971e19133a61bfa94c247ae99d771d8efc11d983e2ea904dab4ca479fa00be3b0372e100225311ffb5b95faed4c32b5794cc618ded1027e6f2a54328a5cd322da6c6ef91151cacfa456680547adf18cde5323869bc03b2c7edd731f5e5c9b9eaa7b2f57d4246d324047482a48d7472650b8d0614a0e133e849a09d37bc9f7921d05397b98e398cd3411dde80d9bd6be4384289a2d1a0416cd914e7520cae962493d31b652a520a9fca7d7e6e9e5df53d719e518125b73ea49af30b720a6d0a71089dcaf04da9ee05c4ede6d0ba376c86282293248a4b36a2ac07a3297d569ad4e958c918317a4d526dae47b07f8c6615a77f5831d146c063b88246e2b3ce7b8f4b75291c339c317e3fbc84563694cd749f021b1e0c076521d685f87497831f19cba89601a344c5d1d08f12b2de9d5d068daf760bf87993e89a2912ab29e3fc79af39db18e982bfe0ee0374c84487cabc1f59bc216d71c38654805cddbc338fc8c14413849ea3ef79444ac6078fb2403ecd84de5b678538be0b2580ecb1926e03643ff29464f943cd729ad386daf1f81ea385e79260cdf78d579281adb72946692d54e94a2fd8530dfb8e5923ce642ec92ccee28f6b21efdff24ec820b4eff26f493278acb485af055881e077cdf3017bc6104b2394fee39343b7c71c20cbf7a3ea96b0c7b603a2ff998d27b16833b028bf30ab668041c8d82225d58bd95f9246de742815067046adbf55eddfddfbc30fea3b8c6659d2756c702f2012395245035bf5338427051b4eb392225aa10179d8b042ba77bc1a37cd66a655ec03aa3aa3c75e05aad4ad38240ee0e6c5af85bc7813f2c0de6eccf5cfba2f6295daf448c042c50c6eba6127f170848cc2034bd61698747a3bee155146d2ab73ba79d969cffcba737bd85b20123a5e3080edba483d831c38c9a4aee9a2fdeb0819665cf28aab91f2317f77d22b29f49d6dbd4ae5b82f9529fb208824f22fdd48666dfc0abe4a9d00dd7d552f4bf6fade29b63ad080614bfe04d9fdca7cff96378e201f6e71cc665e6ae8abd64d125a8c222b03f9153824251db960b4eae41280b681a9fa6c1ec76e94bcd9656aa3df3b57f2da9', 'ad': '' }",
|
||||
'symmetricKey': "{ 'iv': '0146bfcc7b89a3aa055bedae', 't': '7559a4ef7ca495c9605516cc846007a3', 'd': '4de3ab37e73dd6fc294257fe4cb1af26229434297ecdd309e93a941bd1f9913b5916dfe55d62f0d4015c46f66d8fdf4c84ab88c22e4d24428d5fe6c1affce1e14b33760a382b67b4a37262f9ca5a44cb9760b151bbd0748fc18f8f438545df356d99a66c74ff22b623b2b67d9765f80ac6f18af01684e6e3efbce947832ac0bea010c1cde00390e1f3d2187286ff00a43aef8ddc13a98d8f4f771bba1694712623b115f0b2c0e891eccd074ade0b551737b915d0f1242ffcbc1c65555ff7', 'ad': '' }",
|
||||
'email': 'insomnia-user@konghq.com',
|
||||
'accountId': 'acct_64a477e6b59d43a5a607f84b4f73e3ce',
|
||||
'firstName': 'Rick',
|
||||
'lastName': 'Morty',
|
||||
},
|
||||
});
|
||||
},
|
||||
});
|
||||
@@ -11,6 +11,7 @@ import githubApi from './github-api';
|
||||
import gitlabApi from './gitlab-api';
|
||||
import { schema } from './graphql';
|
||||
import { startGRPCServer } from './grpc';
|
||||
import insomniaApi from './insomnia-api';
|
||||
import { oauthRoutes } from './oauth';
|
||||
import { startWebSocketServer } from './websocket';
|
||||
|
||||
@@ -47,6 +48,7 @@ app.use('/auth/basic', basicAuthRouter);
|
||||
|
||||
githubApi(app);
|
||||
gitlabApi(app);
|
||||
insomniaApi(app);
|
||||
|
||||
app.get('/delay/seconds/:duration', (req, res) => {
|
||||
const delaySec = Number.parseInt(req.params.duration || '2');
|
||||
|
||||
@@ -0,0 +1,208 @@
|
||||
import { randomUUID } from 'crypto';
|
||||
import type { Application } from 'express';
|
||||
import { json } from 'express';
|
||||
|
||||
const currentPlan = {
|
||||
isActive: true,
|
||||
period: 'year',
|
||||
planId: 'team',
|
||||
price: 100,
|
||||
quantity: 10,
|
||||
type: 'team',
|
||||
};
|
||||
|
||||
const projectsByOrgId = new Map(Object.entries({
|
||||
'org_7ef19d06-5a24-47ca-bc81-3dea011edec2': [
|
||||
{
|
||||
id: 'proj_org_7ef19d06-5a24-47ca-bc81-3dea011edec2',
|
||||
name: 'Personal Workspace',
|
||||
},
|
||||
],
|
||||
'team_195a6ce0edb1427eb2e8ba7b986072e4': [
|
||||
{
|
||||
id: 'proj_team_195a6ce0edb1427eb2e8ba7b986072e4',
|
||||
name: 'Personal Workspace',
|
||||
},
|
||||
],
|
||||
}));
|
||||
|
||||
const organizations = [
|
||||
// Personal organization
|
||||
{
|
||||
'id': 'org_7ef19d06-5a24-47ca-bc81-3dea011edec2',
|
||||
'name': 'feb56ab4b19347c4b648c99bfa7db363',
|
||||
'display_name': 'Personal workspace',
|
||||
'branding': {
|
||||
'logo_url': '',
|
||||
},
|
||||
'metadata': {
|
||||
'organizationType': 'personal',
|
||||
'ownerAccountId': 'acct_64a477e6b59d43a5a607f84b4f73e3ce',
|
||||
},
|
||||
},
|
||||
// Team Organization: Was a team before the migration now looks like this:
|
||||
// Teams migrated to Organizations have an id that starts with team_ and the team id is the same as the organization id
|
||||
{
|
||||
'id': 'team_195a6ce0edb1427eb2e8ba7b986072e4',
|
||||
'name': '07df6d95b60e4593af0424c74d96637a-team',
|
||||
'display_name': '🦄 Magic',
|
||||
'branding': {
|
||||
'logo_url': '',
|
||||
},
|
||||
'metadata': {
|
||||
'organizationType': 'team',
|
||||
'ownerAccountId': 'acct_64a477e6b59d43a5a607f84b4f73e3ce',
|
||||
},
|
||||
},
|
||||
];
|
||||
|
||||
const organizationFeatures = {
|
||||
features: {
|
||||
gitSync: {
|
||||
enabled: true,
|
||||
},
|
||||
},
|
||||
};
|
||||
|
||||
const user = {
|
||||
'id': 'email|64f0dd619ab0786da330d83a',
|
||||
'email': 'insomnia-user@konghq.com',
|
||||
'name': 'Rick Morty',
|
||||
'picture': '',
|
||||
'bio': 'My BIO',
|
||||
'github': '',
|
||||
'linkedin': '',
|
||||
'twitter': '',
|
||||
'identities': null,
|
||||
'given_name': '',
|
||||
'family_name': '',
|
||||
};
|
||||
|
||||
const whoami = {
|
||||
'sessionExpiry': 4838400,
|
||||
'publicKey': '{"alg":"RSA-OAEP-256","e":"AQAB","ext":true,"key_ops":["encrypt"],"kty":"RSA","n":"pTQVaUaiqggIldSKm6ib6eFRLLoGj9W-2O4gTbiorR-2b8-ZmKUwQ0F-jgYX71AjYaFn5VjOHOHSP6byNAjN7WzJ6A_Z3tytNraLoZfwK8KdfflOCZiZzQeD3nO8BNgh_zEgCHStU61b6N6bSpCKjbyPkmZcOkJfsz0LJMAxrXvFB-I42WYA2vJKReTJKXeYx4d6L_XGNIoYtmGZit8FldT4AucfQUXgdlKvr4_OZmt6hgjwt_Pjcu-_jO7m589mMWMebfUhjte3Lp1jps0MqTOvgRb0FQf5eoBHnL01OZjvFPDKeqlvoz7II9wFNHIKzSvgAKnyemh6DiyPuIukyQ"}',
|
||||
'encPrivateKey': '{"iv":"4a09fba2c412d7ea205b6168","t":"a4fa1a524e89e668444de654f1bd1ba8","d":"b695b6ec7d41327b723e395b3788cc08c89dcf7b4db0811c3e91af4aa9ed1c9cb8132b591fe24498ffcc48c0055c1c0985a48d9e96962961c049cea508b6c38e83dfc831a4b1a82ad3e79a26d6ed3c1c9b73043a0e266cfe6eac661a75f4b9862afe2a81362d640bb2fdb6d0015204d04c322f1cb7f33faa593b538b58bda75b0c5e56583d5a55eea89e74d96ce29d862614414ee298f56105ea3dbc479aea9330618ba3e94efe874b33cd99954b12f27d7ff9e7f981310381fa0b3f1a05fbac71862ecc67ddbf7062f718d1d8bbf03f35afc3a8b1b36b177f278ab8dd12c14c862bca52a2c63bca05c7fc9bd8f1000ddc328ad1b5a72b96f110c3443294129db416bd385d19c73a1b342b4887feffa17639cc96b7b7154903c2de183f73d3116d98c8d32ea8b9627d0a5200da98d28c89c34008d4e6fa4cfbd7e1b7e1f36cfec6d0020b306c7def8d24c6091252764bde2eef74f35bdaa605dc27fcd302d179fcf65d6c7d18d3dd36cf6380bd40a29198a0398a6cb1ab79a71be00f7783b6559a146f1f825d25a990162e923e2dbfdd1ee868c8b63844f9394415ebab9f397c8d78608de00369728744b8344724e5c2f1e4ba95522406bd7042fc271793af32bfa1c2724defc8a88185cc5c2825c0453fcb39dc5ac9147d3ba60006fccca855678521da06b426dfd04333511b7d8184a8960dadefb1ef89f5fa648304adcd79734fea763f7dbd0c2788c64ea302f8e33602ab041aec619661167b2f167a4b2cadc6b7cf0c22867fcdd73528fb5585b9d13f6d90ab36c5ef231bd4f2464650e541e6dead1753487b45a8ade3fe46e2327fd0e32d8adafd4e1d2ffcb2df1ed50718d0d29829f8bf4bc33da524640388b0cb9f640b70f9ef0a1d073bc80abdf975fe77b35f07aee5135e2924661d26e5d299a432c563a3bbc5ff21d1fde07ff2336b32b17067c01adc6697568aabf3ff4882530763f77d96cef2fcc7336e3f8e4a2b8de5df42aaeaeccd9e3681604e677fad555148ced6057d99cab03389bb566b27cc4ea3946a640f05593e5944c74adf5d0649941b8032dc6959bdef917fd7d2da3139b1d3770d411b52752c9299f789ce5de64e802740a8210e1c70e0ffb8aa45a3647b837e2c5d1a7dd676b238268ac7c060bcc771285f21a283c2f0eefb54254086770a4f09140f7b6a118a7df1e06445379080c2cb6a8840b9d70411521107b47751634e3ff6437974ac2e5897e7e15ac8bdbb5325bb1dd09c20f8ac37fa1eaf2765671fd1434460cbf3cc97bf67b19f88b2bfbde99836c27c338b7f19fc20aad90b91e268c87b81aa17026ac5ac74f47c3525fd2d0d584d3b1d75dd360f105f78b2831481802b6a40e88938660d1598947ffb4e7cf75cd67308d6f910be2fb9beafb68d5ea7c3d2f79c3b66223d610a70a6f9ce3c3447bc0acf74e84687c2da5a137b6c14631971e19133a61bfa94c247ae99d771d8efc11d983e2ea904dab4ca479fa00be3b0372e100225311ffb5b95faed4c32b5794cc618ded1027e6f2a54328a5cd322da6c6ef91151cacfa456680547adf18cde5323869bc03b2c7edd731f5e5c9b9eaa7b2f57d4246d324047482a48d7472650b8d0614a0e133e849a09d37bc9f7921d05397b98e398cd3411dde80d9bd6be4384289a2d1a0416cd914e7520cae962493d31b652a520a9fca7d7e6e9e5df53d719e518125b73ea49af30b720a6d0a71089dcaf04da9ee05c4ede6d0ba376c86282293248a4b36a2ac07a3297d569ad4e958c918317a4d526dae47b07f8c6615a77f5831d146c063b88246e2b3ce7b8f4b75291c339c317e3fbc84563694cd749f021b1e0c076521d685f87497831f19cba89601a344c5d1d08f12b2de9d5d068daf760bf87993e89a2912ab29e3fc79af39db18e982bfe0ee0374c84487cabc1f59bc216d71c38654805cddbc338fc8c14413849ea3ef79444ac6078fb2403ecd84de5b678538be0b2580ecb1926e03643ff29464f943cd729ad386daf1f81ea385e79260cdf78d579281adb72946692d54e94a2fd8530dfb8e5923ce642ec92ccee28f6b21efdff24ec820b4eff26f493278acb485af055881e077cdf3017bc6104b2394fee39343b7c71c20cbf7a3ea96b0c7b603a2ff998d27b16833b028bf30ab668041c8d82225d58bd95f9246de742815067046adbf55eddfddfbc30fea3b8c6659d2756c702f2012395245035bf5338427051b4eb392225aa10179d8b042ba77bc1a37cd66a655ec03aa3aa3c75e05aad4ad38240ee0e6c5af85bc7813f2c0de6eccf5cfba2f6295daf448c042c50c6eba6127f170848cc2034bd61698747a3bee155146d2ab73ba79d969cffcba737bd85b20123a5e3080edba483d831c38c9a4aee9a2fdeb0819665cf28aab91f2317f77d22b29f49d6dbd4ae5b82f9529fb208824f22fdd48666dfc0abe4a9d00dd7d552f4bf6fade29b63ad080614bfe04d9fdca7cff96378e201f6e71cc665e6ae8abd64d125a8c222b03f9153824251db960b4eae41280b681a9fa6c1ec76e94bcd9656aa3df3b57f2da9","ad":""}',
|
||||
'encSymmetricKey': '{"iv":"0146bfcc7b89a3aa055bedae","t":"7559a4ef7ca495c9605516cc846007a3","d":"4de3ab37e73dd6fc294257fe4cb1af26229434297ecdd309e93a941bd1f9913b5916dfe55d62f0d4015c46f66d8fdf4c84ab88c22e4d24428d5fe6c1affce1e14b33760a382b67b4a37262f9ca5a44cb9760b151bbd0748fc18f8f438545df356d99a66c74ff22b623b2b67d9765f80ac6f18af01684e6e3efbce947832ac0bea010c1cde00390e1f3d2187286ff00a43aef8ddc13a98d8f4f771bba1694712623b115f0b2c0e891eccd074ade0b551737b915d0f1242ffcbc1c65555ff7","ad":""}',
|
||||
'email': 'insomnia-user@konghq.com',
|
||||
'accountId': 'acct_64a477e6b59d43a5a607f84b4f73e3ce',
|
||||
'firstName': 'Rick',
|
||||
'lastName': 'Morty',
|
||||
};
|
||||
|
||||
export default (app: Application) => {
|
||||
app.post('/api/graphql', json(), (_req, res) => {
|
||||
res.status(200).send({
|
||||
data: {
|
||||
viewer: {
|
||||
name: 'InsomniaUser',
|
||||
email: 'sleepyhead@email.com',
|
||||
},
|
||||
},
|
||||
});
|
||||
});
|
||||
|
||||
// User
|
||||
app.get('/api/v1/user/profile', (_req, res) => {
|
||||
console.log('GET *');
|
||||
res.status(200).send(user);
|
||||
});
|
||||
|
||||
app.get('/api/auth/whoami', (_req, res) => {
|
||||
res.status(200).send(whoami);
|
||||
});
|
||||
|
||||
// Billing
|
||||
app.get('/api/v1/billing/current-plan', json(), (_req, res) => {
|
||||
res.status(200).send(currentPlan);
|
||||
});
|
||||
|
||||
// Organizations
|
||||
app.get('/api/v1/organizations', (_req, res) => {
|
||||
res.status(200).send({
|
||||
organizations: organizations,
|
||||
});
|
||||
});
|
||||
|
||||
app.get('/api/v1/organizations/:orgId/features', (_req, res) => {
|
||||
res.status(200).send(organizationFeatures);
|
||||
});
|
||||
|
||||
// Projects
|
||||
app.get('/api/v1/organizations/:orgId/team-projects', (_req, res) => {
|
||||
res.status(200).send({
|
||||
data: projectsByOrgId.get(_req.params.orgId),
|
||||
});
|
||||
});
|
||||
|
||||
app.delete('/api/v1/organizations/:orgId/team-projects/:projectId', json(), (_req, res) => {
|
||||
const projects = projectsByOrgId.get(_req.params.orgId)?.filter(project => project.id !== _req.params.projectId);
|
||||
if (!projects) {
|
||||
res.status(500).send();
|
||||
return;
|
||||
}
|
||||
projectsByOrgId.set(_req.params.orgId, projects);
|
||||
res.status(200).send();
|
||||
});
|
||||
|
||||
app.patch('/api/v1/organizations/:orgId/team-projects/:projectId', json(), (_req, res) => {
|
||||
const updatedProjects = projectsByOrgId.get(_req.params.orgId)?.map(project => {
|
||||
if (project.id === _req.params.projectId) {
|
||||
return {
|
||||
...project,
|
||||
name: _req.body.name,
|
||||
};
|
||||
}
|
||||
return project;
|
||||
});
|
||||
|
||||
updatedProjects && projectsByOrgId.set(_req.params.orgId, updatedProjects);
|
||||
res.status(200).send();
|
||||
});
|
||||
|
||||
app.post('/api/v1/organizations/:organizationId/team-projects', json(), (_req, res) => {
|
||||
const { organizationId } = _req.params;
|
||||
|
||||
if (organizationId === 'personal') {
|
||||
const personalOrg = organizations.find(org => org.metadata.organizationType === 'personal');
|
||||
|
||||
if (!personalOrg) {
|
||||
res.status(500).send();
|
||||
return;
|
||||
}
|
||||
|
||||
const newProject = {
|
||||
id: `proj_${randomUUID()}`,
|
||||
name: _req.body.name,
|
||||
};
|
||||
|
||||
const projects = [
|
||||
...(projectsByOrgId.get(personalOrg.id) || []),
|
||||
newProject,
|
||||
];
|
||||
|
||||
projectsByOrgId.set(personalOrg.id, projects);
|
||||
res.status(200).send({ ...newProject, organizationId: personalOrg.id });
|
||||
return;
|
||||
}
|
||||
|
||||
const organization = organizations.find(org => org.id === organizationId);
|
||||
|
||||
if (!organization) {
|
||||
res.status(500).send();
|
||||
return;
|
||||
}
|
||||
|
||||
const newProject = {
|
||||
id: `proj_${randomUUID()}`,
|
||||
name: _req.body.name,
|
||||
};
|
||||
|
||||
const projects = [
|
||||
...(projectsByOrgId.get(organization.id) || []),
|
||||
newProject,
|
||||
];
|
||||
|
||||
projectsByOrgId.set(organization.id, projects);
|
||||
res.status(200).send({ ...newProject, organizationId: organization.id });
|
||||
});
|
||||
};
|
||||
@@ -13,7 +13,7 @@ test('can send requests', async ({ app, page }) => {
|
||||
await app.evaluate(async ({ clipboard }, text) => clipboard.writeText(text), text);
|
||||
|
||||
await page.getByRole('menuitemradio', { name: 'Import' }).click();
|
||||
await page.getByText('Clipboard').click();
|
||||
await page.locator('[data-test-id="import-from-clipboard"]').click();
|
||||
await page.getByRole('button', { name: 'Scan' }).click();
|
||||
await page.getByRole('dialog').getByRole('button', { name: 'Import' }).click();
|
||||
await page.getByText('CollectionSmoke testsjust now').click();
|
||||
|
||||
@@ -0,0 +1,75 @@
|
||||
import { copyFixtureDatabase } from '../../playwright/paths';
|
||||
import { test } from '../../playwright/test';
|
||||
|
||||
const testWithLegacyDatabase = test.extend({
|
||||
dataPath: async ({ dataPath }, use) => {
|
||||
await copyFixtureDatabase('insomnia-legacy-db', dataPath);
|
||||
|
||||
await use(dataPath);
|
||||
},
|
||||
userConfig: async ({ userConfig }, use) => {
|
||||
await use({
|
||||
...userConfig,
|
||||
session: undefined,
|
||||
});
|
||||
},
|
||||
});
|
||||
|
||||
// tests new cloud project create but not the vcs part as its too complex to stub the gql endpoint
|
||||
testWithLegacyDatabase('Run data migration to version 8', async ({ page, userConfig }) => {
|
||||
// Migration takes a while, adding this to avoid test timeout before it ends
|
||||
test.slow();
|
||||
|
||||
await page.getByLabel('Continue with Google').click(),
|
||||
|
||||
await page.locator('input[name="code"]').click();
|
||||
await page.locator('input[name="code"]').fill(userConfig.code);
|
||||
|
||||
await page.getByRole('button', { name: 'Log in' }).click();
|
||||
|
||||
// Open migrated Project (Local before migration)
|
||||
await page.getByLabel('Insomnia').click();
|
||||
|
||||
// Open migrated local migrated collection that should now have Insomnia Sync
|
||||
await page.getByLabel('Local Collection').click();
|
||||
await page.getByLabel('Mars', { exact: true }).click();
|
||||
await page.getByRole('option', { name: 'Mars' }).click();
|
||||
await page.getByLabel('Insomnia Sync').isVisible();
|
||||
await page.getByText('Get list of rockets').click();
|
||||
await page.getByTestId('project').click();
|
||||
|
||||
// Open migrated local migrated collection that should have Git Sync
|
||||
await page.getByLabel('Local Project (GIT)').click();
|
||||
await page.getByLabel('OpenAPI').click();
|
||||
await page.getByText('Delete user').click();
|
||||
await page.getByLabel('Git Sync').isVisible();
|
||||
await page.getByTestId('project').click();
|
||||
|
||||
await page.getByLabel('Personal Workspace', { exact: true }).click();
|
||||
|
||||
// Open Team that is migrated to Organization
|
||||
await page.getByRole('link', { name: '🦄' }).click();
|
||||
|
||||
// Open remote migrated collection that should have Insomnia Sync
|
||||
await page.getByLabel('Personal Workspace', { exact: true }).click();
|
||||
await page.getByLabel('Remote Design Document', { exact: true }).click();
|
||||
await page.getByText('Updated user').click();
|
||||
await page.getByLabel('Insomnia Sync').isVisible();
|
||||
await page.getByTestId('project').click();
|
||||
|
||||
// Open remote migrated collection that should have GIT Sync
|
||||
await page.getByLabel('(GIT) Remote Design Document').click();
|
||||
await page.getByText('Updated user').click();
|
||||
await page.getByLabel('Git Sync').isVisible();
|
||||
await page.getByTestId('project').click();
|
||||
|
||||
// Open remote migrated collection that should have Insomnia Sync
|
||||
await page.getByLabel('Remote Collection', { exact: true }).click();
|
||||
await page.getByText('New Request').click();
|
||||
await page.getByLabel('Insomnia Sync').isVisible();
|
||||
await page.getByTestId('project').click();
|
||||
|
||||
// Open remote migrated collection that should have Insomnia Sync
|
||||
await page.getByLabel('Remote Collection', { exact: true }).click();
|
||||
await page.getByLabel('Insomnia Sync').isVisible();
|
||||
});
|
||||
@@ -12,7 +12,7 @@ test.describe('Design interactions', async () => {
|
||||
const text = await loadFixture('unit-test.yaml');
|
||||
await app.evaluate(async ({ clipboard }, text) => clipboard.writeText(text), text);
|
||||
await page.getByRole('menuitemradio', { name: 'Import' }).click();
|
||||
await page.getByText('Clipboard').click();
|
||||
await page.locator('[data-test-id="import-from-clipboard"]').click();
|
||||
await page.getByRole('button', { name: 'Scan' }).click();
|
||||
await page.getByRole('dialog').getByRole('button', { name: 'Import' }).click();
|
||||
await page.getByText('unit-test.yaml').click();
|
||||
@@ -20,37 +20,27 @@ test.describe('Design interactions', async () => {
|
||||
await page.click('a:has-text("Test")');
|
||||
|
||||
// Run tests and check results
|
||||
await page.click('#wrapper >> text=Run Tests');
|
||||
await page.getByLabel('Run all tests').click();
|
||||
await expect(page.locator('.app')).toContainText('Request A is found');
|
||||
await expect(page.locator('.app')).toContainText('Request B is not found');
|
||||
await expect(page.locator('.app')).toContainText('Tests Passed 2/2');
|
||||
await expect(page.locator('.app')).toContainText('Tests passed');
|
||||
|
||||
// Create a new test suite
|
||||
await page.click('text=New Test Suite');
|
||||
await page.click('text=Create Suite');
|
||||
await page.click('button:has-text("New Suite")');
|
||||
await page.click('text=New test suite');
|
||||
|
||||
// Rename test suite
|
||||
await page.getByRole('button', { name: 'New Suite' }).click();
|
||||
await page.getByRole('textbox').fill('New Suite 2');
|
||||
await page.getByRole('textbox').press('Enter');
|
||||
|
||||
// Add a new test
|
||||
await page.locator('text=New Test').nth(1).click();
|
||||
await page.click('div[role="dialog"] button:has-text("New Test")');
|
||||
const label = await page.locator('option', { hasText: 'Request A' }).textContent() || '';
|
||||
await page.locator('select[name="request"]').selectOption({
|
||||
label,
|
||||
});
|
||||
|
||||
await page.click('#wrapper >> text=Run Tests');
|
||||
await expect(page.locator('.app')).toContainText('Tests Passed 1/1');
|
||||
|
||||
// Rename a test
|
||||
// TODO(filipe) - add this in another PR
|
||||
|
||||
// Rename a test suite
|
||||
await page.click('button:has-text("Existing Test Suite")');
|
||||
await page.click('span:has-text("Existing Test Suite")');
|
||||
await page.locator('text=New TestRun Tests >> input[type="text"]').fill('Renamed');
|
||||
await page.locator('text=New TestRun Tests >> input[type="text"]').press('Enter');
|
||||
await page.click('button:has-text("Renamed")');
|
||||
await page.getByLabel('New test').click();
|
||||
|
||||
// Rename test
|
||||
await page.getByRole('button', { name: 'Returns 200' }).click();
|
||||
await page.getByRole('textbox').fill('Returns 200 and works');
|
||||
await page.getByRole('textbox').press('Enter');
|
||||
await page.getByRole('heading', { name: 'Returns 200 and works' }).click();
|
||||
// Use autocomplete inside the test code
|
||||
// TODO(filipe) - add this in another PR
|
||||
});
|
||||
|
||||
@@ -17,7 +17,7 @@ test.describe('gRPC interactions', () => {
|
||||
await app.evaluate(async ({ clipboard }, text) => clipboard.writeText(text), text);
|
||||
|
||||
await page.getByRole('menuitemradio', { name: 'Import' }).click();
|
||||
await page.getByText('Clipboard').click();
|
||||
await page.locator('[data-test-id="import-from-clipboard"]').click();
|
||||
await page.getByRole('button', { name: 'Scan' }).click();
|
||||
await page.getByRole('dialog').getByRole('button', { name: 'Import' }).click();
|
||||
await page.getByText('CollectionPreRelease gRPCjust now').click();
|
||||
|
||||
@@ -14,7 +14,7 @@ test.describe('Plugins', async () => {
|
||||
await page.locator('text=Generate').first().click();
|
||||
|
||||
// check if the plugin shows up on the plugin list
|
||||
await expect(page.locator('.app')).toContainText('insomnia-plugin-demo-example');
|
||||
await page.getByRole('cell', { name: 'insomnia-plugin-demo-example' }).click();
|
||||
});
|
||||
|
||||
test('Check Declarative Config and Kong Kubernetes config', async ({ page }) => {
|
||||
@@ -26,8 +26,8 @@ test.describe('Plugins', async () => {
|
||||
await expect(page.locator('.app')).toContainText('This is a sample server Petstore server');
|
||||
|
||||
// Open declarative config
|
||||
await page.getByTestId('workspace-dropdown').locator('button').click();
|
||||
await page.getByRole('menuitem', { name: 'Declarative Config (Legacy)' }).click();
|
||||
await page.getByLabel('Workspace actions').click();
|
||||
await page.getByRole('menuitemradio', { name: 'Declarative Config (Legacy)' }).click();
|
||||
// Check for declarative config contents
|
||||
await page.getByText('_format_version').click();
|
||||
|
||||
|
||||
@@ -21,7 +21,7 @@ test('Check filter responses by environment preference', async ({ app, page }) =
|
||||
const text = await loadFixture('simple.yaml');
|
||||
await app.evaluate(async ({ clipboard }, text) => clipboard.writeText(text), text);
|
||||
await page.getByRole('menuitemradio', { name: 'Import' }).click();
|
||||
await page.getByText('Clipboard').click();
|
||||
await page.locator('[data-test-id="import-from-clipboard"]').click();
|
||||
await page.getByRole('button', { name: 'Scan' }).click();
|
||||
await page.getByRole('dialog').getByRole('button', { name: 'Import' }).click();
|
||||
await page.getByText('Collectionsimplejust now').click();
|
||||
|
||||
@@ -15,7 +15,7 @@ test('can send requests', async ({ app, page }) => {
|
||||
|
||||
await page.getByRole('button', { name: 'Create in project' }).click();
|
||||
await page.getByRole('menuitemradio', { name: 'Import' }).click();
|
||||
await page.getByText('Clipboard').click();
|
||||
await page.locator('[data-test-id="import-from-clipboard"]').click();
|
||||
await page.getByRole('button', { name: 'Scan' }).click();
|
||||
await page.getByRole('dialog').getByRole('button', { name: 'Import' }).click();
|
||||
|
||||
@@ -93,7 +93,7 @@ test('can cancel requests', async ({ app, page }) => {
|
||||
await app.evaluate(async ({ clipboard }, text) => clipboard.writeText(text), text);
|
||||
|
||||
await page.getByRole('menuitemradio', { name: 'Import' }).click();
|
||||
await page.getByText('Clipboard').click();
|
||||
await page.locator('[data-test-id="import-from-clipboard"]').click();
|
||||
await page.getByRole('button', { name: 'Scan' }).click();
|
||||
await page.getByRole('dialog').getByRole('button', { name: 'Import' }).click();
|
||||
await page.getByText('CollectionSmoke testsjust now').click();
|
||||
|
||||
@@ -8,7 +8,7 @@ test.describe('Cookie editor', async () => {
|
||||
const text = await loadFixture('simple.yaml');
|
||||
await app.evaluate(async ({ clipboard }, text) => clipboard.writeText(text), text);
|
||||
await page.getByRole('menuitemradio', { name: 'Import' }).click();
|
||||
await page.getByText('Clipboard').click();
|
||||
await page.locator('[data-test-id="import-from-clipboard"]').click();
|
||||
await page.getByRole('button', { name: 'Scan' }).click();
|
||||
await page.getByRole('dialog').getByRole('button', { name: 'Import' }).click();
|
||||
await page.getByText('Collectionsimplejust now').click();
|
||||
|
||||
@@ -13,7 +13,7 @@ test.describe('Dashboard', async () => {
|
||||
|
||||
// Create new project
|
||||
await page.getByRole('button', { name: 'Create new Project' }).click();
|
||||
await page.locator('text=Create').nth(1).click();
|
||||
await page.getByRole('button', { name: 'Create', exact: true }).click();
|
||||
|
||||
// Check empty project
|
||||
await expect(page.locator('.app')).toContainText('This is an empty project, to get started create your first resource:');
|
||||
@@ -23,6 +23,7 @@ test.describe('Dashboard', async () => {
|
||||
await page.getByRole('menuitemradio', { name: 'Settings' }).click();
|
||||
await page.getByPlaceholder('My Project').click();
|
||||
await page.getByPlaceholder('My Project').fill('My Project123');
|
||||
await page.getByRole('button', { name: 'Update' }).click();
|
||||
|
||||
// Check that the project name is updated on modal
|
||||
await expect(page.locator('.app')).toContainText('My Project123');
|
||||
@@ -34,12 +35,12 @@ test.describe('Dashboard', async () => {
|
||||
// Delete project
|
||||
await page.getByRole('row', { name: 'My Project' }).getByRole('button', { name: 'Project Actions' }).click();
|
||||
await page.getByRole('menuitemradio', { name: 'Settings' }).click();
|
||||
// Click text=NameActions Delete >> button
|
||||
await page.click('text=NameActions Delete >> button');
|
||||
|
||||
await page.getByRole('button', { name: 'Delete' }).click();
|
||||
await page.getByRole('button', { name: 'Click to confirm' }).click();
|
||||
|
||||
// After deleting project, return to default Insomnia Dashboard
|
||||
await expect(page.locator('.app')).toContainText('Insomnia');
|
||||
await expect(page.locator('.app')).toContainText('Personal Workspace');
|
||||
await expect(page.locator('.app')).not.toContainText('My Project123');
|
||||
await expect(page.locator('.app')).toContainText('New Document');
|
||||
await page.getByLabel('All Files (0)').click();
|
||||
@@ -57,7 +58,7 @@ test.describe('Dashboard', async () => {
|
||||
const text = await loadFixture('multiple-workspaces.yaml');
|
||||
await app.evaluate(async ({ clipboard }, text) => clipboard.writeText(text), text);
|
||||
await page.getByRole('menuitemradio', { name: 'Import' }).click();
|
||||
await page.getByText('Clipboard').click();
|
||||
await page.locator('[data-test-id="import-from-clipboard"]').click();
|
||||
await page.getByRole('button', { name: 'Scan' }).click();
|
||||
await page.getByRole('dialog').getByRole('button', { name: 'Import' }).click();
|
||||
await page.getByText('CollectionSmoke testsjust now').click();
|
||||
@@ -94,7 +95,7 @@ test.describe('Dashboard', async () => {
|
||||
// Create new document
|
||||
await page.getByRole('button', { name: 'Create in project' }).click();
|
||||
await page.getByRole('menuitemradio', { name: 'Design Document' }).click();
|
||||
await page.locator('text=Create').nth(1).click();
|
||||
await page.getByRole('button', { name: 'Create', exact: true }).click();
|
||||
|
||||
await page.getByTestId('project').click();
|
||||
|
||||
@@ -131,7 +132,7 @@ test.describe('Dashboard', async () => {
|
||||
// Create new collection
|
||||
await page.getByRole('button', { name: 'Create in project' }).click();
|
||||
await page.getByRole('menuitemradio', { name: 'Request Collection' }).click();
|
||||
await page.locator('text=Create').nth(1).click();
|
||||
await page.getByRole('button', { name: 'Create', exact: true }).click();
|
||||
|
||||
await page.getByTestId('project').click();
|
||||
|
||||
|
||||
@@ -10,7 +10,7 @@ test.describe('Debug-Sidebar', async () => {
|
||||
const text = await loadFixture('simple.yaml');
|
||||
await app.evaluate(async ({ clipboard }, text) => clipboard.writeText(text), text);
|
||||
await page.getByRole('menuitemradio', { name: 'Import' }).click();
|
||||
await page.getByText('Clipboard').click();
|
||||
await page.locator('[data-test-id="import-from-clipboard"]').click();
|
||||
await page.getByRole('button', { name: 'Scan' }).click();
|
||||
await page.getByRole('dialog').getByRole('button', { name: 'Import' }).click();
|
||||
await page.getByText('Collectionsimplejust now').click();
|
||||
@@ -58,8 +58,8 @@ test.describe('Debug-Sidebar', async () => {
|
||||
});
|
||||
|
||||
test('Open properties of the collection', async ({ page }) => {
|
||||
await page.getByTestId('workspace-dropdown').locator('button').click();
|
||||
await page.getByRole('menuitem', { name: 'Settings' }).click();
|
||||
await page.getByLabel('Workspace actions', { exact: true }).click();
|
||||
await page.getByRole('menuitemradio', { name: 'Settings' }).click();
|
||||
await page.getByText('Collection Settings').click();
|
||||
});
|
||||
|
||||
|
||||
@@ -8,7 +8,7 @@ test.describe('Environment Editor', async () => {
|
||||
const text = await loadFixture('environments.yaml');
|
||||
await app.evaluate(async ({ clipboard }, text) => clipboard.writeText(text), text);
|
||||
await page.getByRole('menuitemradio', { name: 'Import' }).click();
|
||||
await page.getByText('Clipboard').click();
|
||||
await page.locator('[data-test-id="import-from-clipboard"]').click();
|
||||
await page.getByRole('button', { name: 'Scan' }).click();
|
||||
await page.getByRole('dialog').getByRole('button', { name: 'Import' }).click();
|
||||
await page.getByText('Collectionenvironments').click();
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import { test } from '../../playwright/test';
|
||||
test('Clone from github', async ({ page }) => {
|
||||
await page.getByRole('button', { name: 'Git Clone' }).click();
|
||||
await page.getByLabel('Clone git repository').click();
|
||||
await page.getByRole('tab', { name: ' Git' }).click();
|
||||
await page.getByPlaceholder('https://github.com/org/repo.git').fill('https://github.com/gatzjames/insomnia-git-example.git');
|
||||
await page.getByPlaceholder('Name').fill('J');
|
||||
@@ -13,8 +13,8 @@ test('Clone from github', async ({ page }) => {
|
||||
test('Sign in with GitHub', async ({ app, page }) => {
|
||||
await page.getByRole('button', { name: 'New Document' }).click();
|
||||
await page.getByRole('dialog').getByRole('button', { name: 'Create' }).click();
|
||||
await page.getByRole('button', { name: 'Git Sync' }).click();
|
||||
await page.getByRole('button', { name: 'Setup Git Sync' }).click();
|
||||
await page.getByLabel('Insomnia Sync').click();
|
||||
await page.getByLabel('Setup Git Sync').click();
|
||||
|
||||
await page.getByRole('tab', { name: 'Github' }).click();
|
||||
|
||||
|
||||
@@ -14,7 +14,7 @@ test('can render schema and send GraphQL requests', async ({ app, page }) => {
|
||||
|
||||
// Import from clipboard
|
||||
await page.getByRole('menuitemradio', { name: 'Import' }).click();
|
||||
await page.getByText('Clipboard').click();
|
||||
await page.locator('[data-test-id="import-from-clipboard"]').click();
|
||||
await page.getByRole('button', { name: 'Scan' }).click();
|
||||
await page.getByRole('dialog').getByRole('button', { name: 'Import' }).click();
|
||||
await page.getByText('CollectionSmoke GraphQLjust now').click();
|
||||
@@ -51,7 +51,7 @@ test('can send GraphQL requests after editing and prettifying query', async ({ a
|
||||
const text = await loadFixture('graphql.yaml');
|
||||
await app.evaluate(async ({ clipboard }, text) => clipboard.writeText(text), text);
|
||||
await page.getByRole('menuitemradio', { name: 'Import' }).click();
|
||||
await page.getByText('Clipboard').click();
|
||||
await page.locator('[data-test-id="import-from-clipboard"]').click();
|
||||
await page.getByRole('button', { name: 'Scan' }).click();
|
||||
await page.getByRole('dialog').getByRole('button', { name: 'Import' }).click();
|
||||
await page.getByText('CollectionSmoke GraphQLjust now').click();
|
||||
|
||||
@@ -16,7 +16,7 @@ test('can send gRPC requests with reflection', async ({ app, page }) => {
|
||||
await app.evaluate(async ({ clipboard }, text) => clipboard.writeText(text), text);
|
||||
|
||||
await page.getByRole('menuitemradio', { name: 'Import' }).click();
|
||||
await page.getByText('Clipboard').click();
|
||||
await page.locator('[data-test-id="import-from-clipboard"]').click();
|
||||
await page.getByRole('button', { name: 'Scan' }).click();
|
||||
await page.getByRole('dialog').getByRole('button', { name: 'Import' }).click();
|
||||
await page.getByText('CollectionPreRelease gRPCjust now').click();
|
||||
|
||||
@@ -3,8 +3,8 @@ import { test } from '../../playwright/test';
|
||||
test('Sign in with Gitlab', async ({ app, page }) => {
|
||||
await page.getByRole('button', { name: 'New Document' }).click();
|
||||
await page.getByRole('dialog').getByRole('button', { name: 'Create' }).click();
|
||||
await page.getByRole('button', { name: 'Git Sync' }).click();
|
||||
await page.getByRole('button', { name: 'Setup Git Sync' }).click();
|
||||
await page.getByLabel('Insomnia Sync').click();
|
||||
await page.getByLabel('Setup Git Sync').click();
|
||||
await page.getByRole('tab', { name: 'GitLab' }).click();
|
||||
|
||||
const fakeGitLabOAuthWebFlow = app.evaluate(electron => {
|
||||
|
||||
@@ -23,7 +23,7 @@ test('can make oauth2 requests', async ({ app, page }) => {
|
||||
await app.evaluate(async ({ clipboard }, text) => clipboard.writeText(text), text);
|
||||
|
||||
await page.getByRole('menuitemradio', { name: 'Import' }).click();
|
||||
await page.getByText('Clipboard').click();
|
||||
await page.locator('[data-test-id="import-from-clipboard"]').click();
|
||||
await page.getByRole('button', { name: 'Scan' }).click();
|
||||
await page.getByRole('dialog').getByRole('button', { name: 'Import' }).click();
|
||||
await page.getByText('CollectionOAuth Testingjust now').click();
|
||||
|
||||
@@ -16,7 +16,7 @@ test('can make websocket connection', async ({ app, page }) => {
|
||||
await app.evaluate(async ({ clipboard }, text) => clipboard.writeText(text), text);
|
||||
|
||||
await page.getByRole('menuitemradio', { name: 'Import' }).click();
|
||||
await page.getByText('Clipboard').click();
|
||||
await page.locator('[data-test-id="import-from-clipboard"]').click();
|
||||
await page.getByRole('button', { name: 'Scan' }).click();
|
||||
await page.getByRole('dialog').getByRole('button', { name: 'Import' }).click();
|
||||
await page.getByText('CollectionWebSocketsjust now').click();
|
||||
|
||||
@@ -58,6 +58,7 @@
|
||||
"electron-context-menu": "^3.6.1",
|
||||
"electron-log": "^4.4.8",
|
||||
"grpc-reflection-js": "0.3.0",
|
||||
"gsap": "^3.11.3",
|
||||
"hawk": "9.0.1",
|
||||
"hkdf": "^0.0.2",
|
||||
"hosted-git-info": "5.2.1",
|
||||
|
||||
@@ -6,6 +6,7 @@ type LoginCallback = (isLoggedIn: boolean) => void;
|
||||
|
||||
export interface WhoamiResponse {
|
||||
sessionAge: number;
|
||||
sessionExpiry: number;
|
||||
accountId: string;
|
||||
email: string;
|
||||
firstName: string;
|
||||
@@ -29,6 +30,7 @@ export interface WhoamiResponse {
|
||||
export interface SessionData {
|
||||
accountId: string;
|
||||
id: string;
|
||||
sessionExpiry: Date;
|
||||
email: string;
|
||||
firstName: string;
|
||||
lastName: string;
|
||||
@@ -46,6 +48,7 @@ export function onLoginLogout(loginCallback: LoginCallback) {
|
||||
export async function absorbKey(sessionId: string, key: string) {
|
||||
// Get and store some extra info (salts and keys)
|
||||
const {
|
||||
sessionExpiry,
|
||||
publicKey,
|
||||
encPrivateKey,
|
||||
encSymmetricKey,
|
||||
@@ -55,9 +58,13 @@ export async function absorbKey(sessionId: string, key: string) {
|
||||
lastName,
|
||||
} = await _whoami(sessionId);
|
||||
const symmetricKeyStr = crypt.decryptAES(key, JSON.parse(encSymmetricKey));
|
||||
|
||||
const sessionExpiryDate = new Date(Date.now() + (sessionExpiry * 1000));
|
||||
|
||||
// Store the information for later
|
||||
setSessionData(
|
||||
sessionId,
|
||||
sessionExpiryDate,
|
||||
accountId,
|
||||
firstName,
|
||||
lastName,
|
||||
@@ -98,7 +105,7 @@ export async function changePasswordWithToken(rawNewPassphrase: string, confirma
|
||||
const symmetricKey = JSON.stringify(_getSymmetricKey());
|
||||
const newEncSymmetricKeyJSON = crypt.encryptAES(newSecret, symmetricKey);
|
||||
const newEncSymmetricKey = JSON.stringify(newEncSymmetricKeyJSON);
|
||||
return window.main.insomniaFetch({
|
||||
await window.main.insomniaFetch({
|
||||
method: 'POST',
|
||||
path: '/auth/change-password',
|
||||
data: {
|
||||
@@ -113,7 +120,7 @@ export async function changePasswordWithToken(rawNewPassphrase: string, confirma
|
||||
}
|
||||
|
||||
export function sendPasswordChangeCode() {
|
||||
return window.main.insomniaFetch({
|
||||
window.main.insomniaFetch({
|
||||
method: 'POST',
|
||||
path: '/auth/send-password-code',
|
||||
sessionId: getCurrentSessionId(),
|
||||
@@ -143,7 +150,19 @@ export function getPrivateKey() {
|
||||
|
||||
export function getCurrentSessionId() {
|
||||
if (window) {
|
||||
return window.localStorage.getItem('currentSessionId');
|
||||
const sessionId = window.localStorage.getItem('currentSessionId');
|
||||
try {
|
||||
const { sessionExpiry } = JSON.parse(window.localStorage.getItem(_getSessionKey(sessionId)) || '{}');
|
||||
const isExpired = sessionExpiry && new Date(sessionExpiry).getTime() < Date.now();
|
||||
if (isExpired) {
|
||||
console.log('Session has expired', sessionExpiry);
|
||||
return '';
|
||||
}
|
||||
return sessionId;
|
||||
} catch (e) {
|
||||
console.log('Error in expiry logic', e);
|
||||
return '';
|
||||
}
|
||||
} else {
|
||||
return '';
|
||||
}
|
||||
@@ -195,6 +214,7 @@ export async function logout() {
|
||||
/** Set data for the new session and store it encrypted with the sessionId */
|
||||
export function setSessionData(
|
||||
id: string,
|
||||
sessionExpiry: Date,
|
||||
accountId: string,
|
||||
firstName: string,
|
||||
lastName: string,
|
||||
@@ -205,6 +225,7 @@ export function setSessionData(
|
||||
) {
|
||||
const sessionData: SessionData = {
|
||||
id,
|
||||
sessionExpiry,
|
||||
accountId,
|
||||
symmetricKey,
|
||||
publicKey,
|
||||
@@ -219,13 +240,6 @@ export function setSessionData(
|
||||
window.localStorage.setItem('currentSessionId', id);
|
||||
return sessionData;
|
||||
}
|
||||
export async function listTeams() {
|
||||
return window.main.insomniaFetch({
|
||||
method: 'GET',
|
||||
path: '/api/teams',
|
||||
sessionId: getCurrentSessionId(),
|
||||
});
|
||||
}
|
||||
|
||||
// ~~~~~~~~~~~~~~~~ //
|
||||
// Helper Functions //
|
||||
@@ -247,7 +261,7 @@ async function _whoami(sessionId: string | null = null): Promise<WhoamiResponse>
|
||||
}
|
||||
|
||||
function _getAuthSalts(email: string) {
|
||||
return window.main.insomniaFetch({
|
||||
return window.main.insomniaFetch<{ saltKey: string; saltAuth: string }>({
|
||||
method: 'POST',
|
||||
path: '/auth/login-s',
|
||||
data: { email },
|
||||
|
||||
@@ -10,6 +10,7 @@ describe('exportWorkspacesHAR() and exportRequestsHAR()', () => {
|
||||
beforeEach(async () => {
|
||||
await globalBeforeEach();
|
||||
await models.project.all();
|
||||
await models.settings.getOrCreate();
|
||||
});
|
||||
|
||||
it('exports a single workspace and some requests only as an HTTP Archive', async () => {
|
||||
|
||||
@@ -14,6 +14,7 @@ describe('export', () => {
|
||||
beforeEach(async () => {
|
||||
await globalBeforeEach();
|
||||
await models.project.all();
|
||||
await models.settings.getOrCreate();
|
||||
});
|
||||
|
||||
describe('exportHar()', () => {
|
||||
|
||||
@@ -3,8 +3,7 @@ import fs from 'fs';
|
||||
import path from 'path';
|
||||
|
||||
import { globalBeforeEach } from '../../__jest__/before-each';
|
||||
import { request, requestGroup, workspace } from '../../models';
|
||||
import { DEFAULT_PROJECT_ID } from '../../models/project';
|
||||
import { project, request, requestGroup, workspace } from '../../models';
|
||||
import * as importUtil from '../import';
|
||||
|
||||
describe('isApiSpecImport()', () => {
|
||||
@@ -39,20 +38,22 @@ describe('importRaw()', () => {
|
||||
const fixturePath = path.join(__dirname, '..', '__fixtures__', 'curl', 'complex-input.sh');
|
||||
const content = fs.readFileSync(fixturePath, 'utf8').toString();
|
||||
|
||||
const projectToImportTo = await project.create();
|
||||
|
||||
const scanResult = await importUtil.scanResources({
|
||||
content,
|
||||
});
|
||||
|
||||
expect(scanResult.type.id).toBe('curl');
|
||||
expect(scanResult.type?.id).toBe('curl');
|
||||
expect(scanResult.errors.length).toBe(0);
|
||||
|
||||
await importUtil.importResourcesToProject({
|
||||
projectId: DEFAULT_PROJECT_ID,
|
||||
projectId: projectToImportTo._id,
|
||||
});
|
||||
|
||||
const workspacesCount = await workspace.count();
|
||||
const projectWorkspaces = await workspace.findByParentId(
|
||||
DEFAULT_PROJECT_ID
|
||||
projectToImportTo._id
|
||||
);
|
||||
const curlRequests = await request.findByParentId(projectWorkspaces[0]._id);
|
||||
|
||||
@@ -97,21 +98,21 @@ describe('importRaw()', () => {
|
||||
it('should import a postman collection to a new workspace', async () => {
|
||||
const fixturePath = path.join(__dirname, '..', '__fixtures__', 'postman', 'aws-signature-auth-v2_0-input.json');
|
||||
const content = fs.readFileSync(fixturePath, 'utf8').toString();
|
||||
|
||||
const projectToImportTo = await project.create();
|
||||
const scanResult = await importUtil.scanResources({
|
||||
content,
|
||||
});
|
||||
|
||||
expect(scanResult.type.id).toBe('postman');
|
||||
expect(scanResult.type?.id).toBe('postman');
|
||||
expect(scanResult.errors.length).toBe(0);
|
||||
|
||||
await importUtil.importResourcesToProject({
|
||||
projectId: DEFAULT_PROJECT_ID,
|
||||
projectId: projectToImportTo._id,
|
||||
});
|
||||
|
||||
const workspacesCount = await workspace.count();
|
||||
const projectWorkspaces = await workspace.findByParentId(
|
||||
DEFAULT_PROJECT_ID
|
||||
projectToImportTo._id
|
||||
);
|
||||
|
||||
const requestGroups = await requestGroup.findByParentId(projectWorkspaces[0]._id);
|
||||
|
||||
@@ -17,6 +17,7 @@ describe('render tests', () => {
|
||||
beforeEach(async () => {
|
||||
await globalBeforeEach();
|
||||
await models.project.all();
|
||||
await models.settings.getOrCreate();
|
||||
envBuilder.reset();
|
||||
reqGroupBuilder.reset();
|
||||
});
|
||||
|
||||
@@ -5,6 +5,10 @@ import { KeyCombination } from './settings';
|
||||
const env = process['env'];
|
||||
|
||||
// App Stuff
|
||||
export const getSkipOnboarding = () => env.INSOMNIA_SKIP_ONBOARDING;
|
||||
export const getInsomniaSession = () => env.INSOMNIA_SESSION;
|
||||
export const getInsomniaSecretKey = () => env.INSOMNIA_SECRET_KEY;
|
||||
export const getInsomniaPublicKey = () => env.INSOMNIA_PUBLIC_KEY;
|
||||
export const getAppVersion = () => version;
|
||||
export const getProductName = () => appConfig.productName;
|
||||
export const getAppDefaultTheme = () => appConfig.theme;
|
||||
@@ -132,6 +136,7 @@ export enum UpdateURL {
|
||||
|
||||
// API
|
||||
export const getApiBaseURL = () => env.INSOMNIA_API_URL || 'https://api.insomnia.rest';
|
||||
export const getAIServiceURL = () => env.INSOMNIA_AI_URL || 'https://ai.insomnia.rest';
|
||||
|
||||
export const getUpdatesBaseURL = () => env.INSOMNIA_UPDATES_URL || 'https://updates.insomnia.rest';
|
||||
|
||||
|
||||
@@ -17,11 +17,12 @@ import { generateId } from './misc';
|
||||
export interface Query {
|
||||
_id?: string | SpecificQuery;
|
||||
parentId?: string | SpecificQuery | null;
|
||||
remoteId?: string | null;
|
||||
remoteId?: string | SpecificQuery | null;
|
||||
plugin?: string;
|
||||
key?: string;
|
||||
environmentId?: string | null;
|
||||
protoFileId?: string;
|
||||
name?: string | SpecificQuery;
|
||||
}
|
||||
|
||||
type Sort = Record<string, any>;
|
||||
@@ -35,6 +36,7 @@ export interface SpecificQuery {
|
||||
$gt?: number;
|
||||
$in?: string[];
|
||||
$nin?: string[];
|
||||
$ne?: string | null;
|
||||
}
|
||||
|
||||
export type ModelQuery<T extends BaseModel> = Partial<Record<keyof T, SpecificQuery>>;
|
||||
|
||||
@@ -0,0 +1,226 @@
|
||||
import { mkdir, writeFile } from 'fs/promises';
|
||||
import { join } from 'path';
|
||||
|
||||
import { apiSpec, cookieJar, environment, grpcRequest, project, protoDirectory, protoFile, request, requestGroup, unitTest, unitTestSuite, webSocketPayload, webSocketRequest, workspace } from '../models';
|
||||
import { ApiSpec } from '../models/api-spec';
|
||||
import { CookieJar } from '../models/cookie-jar';
|
||||
import { Environment } from '../models/environment';
|
||||
import { GrpcRequest } from '../models/grpc-request';
|
||||
import type { Project } from '../models/project';
|
||||
import { ProtoDirectory } from '../models/proto-directory';
|
||||
import { ProtoFile } from '../models/proto-file';
|
||||
import { Request } from '../models/request';
|
||||
import { RequestGroup } from '../models/request-group';
|
||||
import { UnitTest } from '../models/unit-test';
|
||||
import { UnitTestSuite } from '../models/unit-test-suite';
|
||||
import { WebSocketPayload } from '../models/websocket-payload';
|
||||
import { WebSocketRequest } from '../models/websocket-request';
|
||||
import { Workspace } from '../models/workspace';
|
||||
import type { Insomnia4Data } from '../utils/importers/importers';
|
||||
import { invariant } from '../utils/invariant';
|
||||
import { EXPORT_TYPE_API_SPEC, EXPORT_TYPE_COOKIE_JAR, EXPORT_TYPE_ENVIRONMENT, EXPORT_TYPE_GRPC_REQUEST, EXPORT_TYPE_PROTO_DIRECTORY, EXPORT_TYPE_PROTO_FILE, EXPORT_TYPE_REQUEST, EXPORT_TYPE_REQUEST_GROUP, EXPORT_TYPE_UNIT_TEST, EXPORT_TYPE_UNIT_TEST_SUITE, EXPORT_TYPE_WEBSOCKET_PAYLOAD, EXPORT_TYPE_WEBSOCKET_REQUEST, EXPORT_TYPE_WORKSPACE } from './constants';
|
||||
import { database } from './database';
|
||||
|
||||
const exportTypeByModelType = (type: string) => ({
|
||||
[request.type]: EXPORT_TYPE_REQUEST,
|
||||
[webSocketPayload.type]: EXPORT_TYPE_WEBSOCKET_PAYLOAD,
|
||||
[webSocketRequest.type]: EXPORT_TYPE_WEBSOCKET_REQUEST,
|
||||
[grpcRequest.type]: EXPORT_TYPE_GRPC_REQUEST,
|
||||
[requestGroup.type]: EXPORT_TYPE_REQUEST_GROUP,
|
||||
[unitTestSuite.type]: EXPORT_TYPE_UNIT_TEST_SUITE,
|
||||
[unitTest.type]: EXPORT_TYPE_UNIT_TEST,
|
||||
[workspace.type]: EXPORT_TYPE_WORKSPACE,
|
||||
[cookieJar.type]: EXPORT_TYPE_COOKIE_JAR,
|
||||
[environment.type]: EXPORT_TYPE_ENVIRONMENT,
|
||||
[apiSpec.type]: EXPORT_TYPE_API_SPEC,
|
||||
[protoFile.type]: EXPORT_TYPE_PROTO_FILE,
|
||||
[protoDirectory.type]: EXPORT_TYPE_PROTO_DIRECTORY,
|
||||
}[type] || undefined);
|
||||
|
||||
export async function exportWorkspaceData({
|
||||
workspaceId,
|
||||
dirPath,
|
||||
}: {
|
||||
workspaceId: string;
|
||||
dirPath: string;
|
||||
}) {
|
||||
const workspaceToExport = await database.get<Workspace>(workspace.type, workspaceId);
|
||||
invariant(workspaceToExport, `Workspace ${workspaceId} not found`);
|
||||
const workspaceIds = [workspaceId];
|
||||
|
||||
const getRequestGroups = async ({ $in }: { $in: string[] }): Promise<RequestGroup[]> => {
|
||||
const requestGroups = await database.find<RequestGroup>(requestGroup.type, {
|
||||
parentId: {
|
||||
$in,
|
||||
},
|
||||
});
|
||||
|
||||
const requestGroupIds = requestGroups.map(requestGroup => requestGroup._id);
|
||||
|
||||
const childRequestGroups = requestGroupIds.length > 0 ? await getRequestGroups({
|
||||
$in: requestGroupIds,
|
||||
}) : [];
|
||||
|
||||
return [
|
||||
...requestGroups,
|
||||
...childRequestGroups,
|
||||
];
|
||||
};
|
||||
|
||||
const allRequestGroups = await getRequestGroups({
|
||||
$in: workspaceIds,
|
||||
});
|
||||
|
||||
const getProtoDirectories = async ({ $in }: { $in: string[] }): Promise<ProtoDirectory[]> => {
|
||||
const protoDirectories = await database.find<ProtoDirectory>(protoDirectory.type, {
|
||||
parentId: {
|
||||
$in,
|
||||
},
|
||||
});
|
||||
|
||||
const protoDirectoryIds = protoDirectories.map(protoDirectory => protoDirectory._id);
|
||||
|
||||
const childProtoDirectories = protoDirectoryIds.length > 0 ? await getProtoDirectories({
|
||||
$in: protoDirectoryIds,
|
||||
}) : [];
|
||||
|
||||
return [
|
||||
...protoDirectories,
|
||||
...childProtoDirectories,
|
||||
];
|
||||
};
|
||||
|
||||
const allProtoDirectories = await getProtoDirectories({
|
||||
$in: workspaceIds,
|
||||
});
|
||||
|
||||
const protoFiles = await database.find<ProtoFile>(protoFile.type, {
|
||||
parentId: {
|
||||
$in: allProtoDirectories.map(protoDirectory => protoDirectory._id),
|
||||
},
|
||||
});
|
||||
|
||||
const requests = await database.find<Request>(request.type, {
|
||||
parentId: {
|
||||
$in: [
|
||||
...workspaceIds,
|
||||
...allRequestGroups.map(requestGroup => requestGroup._id),
|
||||
],
|
||||
},
|
||||
});
|
||||
|
||||
const grpcRequests = await database.find<GrpcRequest>(grpcRequest.type, {
|
||||
parentId: {
|
||||
$in: [
|
||||
...workspaceIds,
|
||||
...allRequestGroups.map(requestGroup => requestGroup._id),
|
||||
],
|
||||
},
|
||||
});
|
||||
|
||||
const webSocketRequests = await database.find<WebSocketRequest>(webSocketRequest.type, {
|
||||
parentId: {
|
||||
$in: [
|
||||
...workspaceIds,
|
||||
...allRequestGroups.map(requestGroup => requestGroup._id),
|
||||
],
|
||||
},
|
||||
});
|
||||
|
||||
const baseEnvironments = await database.find<Environment>(environment.type, {
|
||||
parentId: {
|
||||
$in: workspaceIds,
|
||||
},
|
||||
});
|
||||
|
||||
const environments = await database.find<Environment>(environment.type, {
|
||||
parentId: {
|
||||
$in: baseEnvironments.map(environment => environment._id),
|
||||
},
|
||||
});
|
||||
|
||||
const cookieJars = await database.find<CookieJar>(cookieJar.type, {
|
||||
parentId: {
|
||||
$in: workspaceIds,
|
||||
},
|
||||
});
|
||||
|
||||
const apiSpecs = await database.find<ApiSpec>(apiSpec.type, {
|
||||
parentId: {
|
||||
$in: workspaceIds,
|
||||
},
|
||||
});
|
||||
|
||||
const unitTestSuites = await database.find<UnitTestSuite>(unitTestSuite.type, {
|
||||
parentId: {
|
||||
$in: workspaceIds,
|
||||
},
|
||||
});
|
||||
|
||||
const unitTests = await database.find<UnitTest>(unitTest.type, {
|
||||
parentId: {
|
||||
$in: unitTestSuites.map(unitTestSuite => unitTestSuite._id),
|
||||
},
|
||||
});
|
||||
const webSocketPayloads = await database.find<WebSocketPayload>(webSocketPayload.type, {
|
||||
parentId: {
|
||||
$in: webSocketRequests.map(webSocketRequest => webSocketRequest._id),
|
||||
},
|
||||
});
|
||||
|
||||
const insomniaExport: Insomnia4Data = {
|
||||
_type: 'export',
|
||||
__export_format: 4,
|
||||
__export_date: new Date(),
|
||||
__export_source: 'insomnia.desktop.app:v2021.5.0',
|
||||
resources: [
|
||||
workspaceToExport,
|
||||
...requests,
|
||||
...allRequestGroups,
|
||||
...environments,
|
||||
...cookieJars,
|
||||
...apiSpecs,
|
||||
...protoFiles,
|
||||
...allProtoDirectories,
|
||||
...unitTests,
|
||||
...unitTestSuites,
|
||||
...webSocketPayloads,
|
||||
...webSocketRequests,
|
||||
...grpcRequests,
|
||||
].map(({ type, ...model }) => ({
|
||||
...model,
|
||||
_type: exportTypeByModelType(type),
|
||||
})),
|
||||
};
|
||||
|
||||
const filePath = join(dirPath, workspaceId + '.json');
|
||||
|
||||
try {
|
||||
await writeFile(filePath, JSON.stringify(insomniaExport));
|
||||
} catch (error) {
|
||||
console.error(error);
|
||||
}
|
||||
}
|
||||
|
||||
export async function exportAllData({
|
||||
dirPath,
|
||||
}: {
|
||||
dirPath: string;
|
||||
}): Promise<void> {
|
||||
const insomniaExportFolder = join(dirPath, `insomnia-export.${Date.now()}`);
|
||||
await mkdir(insomniaExportFolder);
|
||||
const projects = await database.all<Project>(project.type);
|
||||
|
||||
for (const project of projects) {
|
||||
const workspaces = await database.find<Workspace>(workspace.type, {
|
||||
parentId: project._id,
|
||||
});
|
||||
|
||||
for (const workspace of workspaces) {
|
||||
await exportWorkspaceData({
|
||||
workspaceId: workspace._id,
|
||||
dirPath: insomniaExportFolder,
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -146,7 +146,6 @@ export async function exportRequestsData(
|
||||
format: 'json' | 'yaml',
|
||||
) {
|
||||
const data: Insomnia4Data = {
|
||||
// @ts-expect-error -- TSCONVERSION maybe this needs to be added to the upstream type?
|
||||
_type: 'export',
|
||||
__export_format: EXPORT_FORMAT,
|
||||
__export_date: new Date(),
|
||||
|
||||
@@ -55,7 +55,7 @@ export async function getSendRequestCallbackMemDb(environmentId: string, memDB:
|
||||
const workspace = await models.workspace.getById(workspaceId);
|
||||
invariant(workspace, 'failed to find workspace');
|
||||
|
||||
const settings = await models.settings.getOrCreate();
|
||||
const settings = await models.settings.get();
|
||||
invariant(settings, 'failed to create settings');
|
||||
const clientCertificates = await models.clientCertificate.findByParentId(workspaceId);
|
||||
const caCert = await models.caCertificate.findByParentId(workspaceId);
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
<meta charset="utf-8" />
|
||||
<meta
|
||||
http-equiv="Content-Security-Policy"
|
||||
content="font-src 'self' data:; connect-src * data:; default-src * insomnia://*; img-src blob: data: * insomnia://*; script-src 'self' 'unsafe-eval'; style-src 'self' 'unsafe-inline'; media-src blob: data: mediastream: * insomnia://*;"
|
||||
content="font-src 'self' data:; connect-src * data: api: insomnia-event-source:; default-src * insomnia://*; img-src blob: data: * insomnia://*; script-src 'self' 'unsafe-eval'; style-src 'self' 'unsafe-inline'; media-src blob: data: mediastream: * insomnia://*;"
|
||||
/>
|
||||
<link rel="stylesheet" href="./ui/css/styles.css" />
|
||||
</head>
|
||||
@@ -37,7 +37,7 @@
|
||||
cy="36"
|
||||
r="36"
|
||||
fill="none"
|
||||
stroke="var(--hl)"
|
||||
stroke="var(--hl, rgb(130, 130, 130))"
|
||||
stroke-opacity="0.1"
|
||||
stroke-width="4px"
|
||||
transform="translate(-323 -111) translate(359.016 147.016) scale(4.24956)"
|
||||
@@ -47,7 +47,7 @@
|
||||
cy="36"
|
||||
r="36"
|
||||
fill="none"
|
||||
stroke="var(--hl)"
|
||||
stroke="var(--hl, rgb(130, 130, 130))"
|
||||
stroke-opacity="0.8"
|
||||
stroke-width="4px"
|
||||
stroke-dasharray="56,172,0,0"
|
||||
|
||||
@@ -9,6 +9,7 @@ import { userDataFolder } from '../config/config.json';
|
||||
import { changelogUrl, getAppVersion, isDevelopment, isMac } from './common/constants';
|
||||
import { database } from './common/database';
|
||||
import log, { initializeLogging } from './common/log';
|
||||
import { registerInsomniaStreamProtocol } from './main/api.protocol';
|
||||
import { backupIfNewerVersionAvailable } from './main/backup';
|
||||
import { registerElectronHandlers } from './main/ipc/electron';
|
||||
import { registergRPCHandlers } from './main/ipc/grpc';
|
||||
@@ -25,6 +26,7 @@ import type { ToastNotification } from './ui/components/toast';
|
||||
|
||||
initializeSentry();
|
||||
|
||||
registerInsomniaStreamProtocol();
|
||||
// Handle potential auto-update
|
||||
if (checkIfRestartNeeded()) {
|
||||
process.exit(0);
|
||||
|
||||
@@ -4,19 +4,18 @@ import { v4 as uuidv4 } from 'uuid';
|
||||
import * as session from '../account/session';
|
||||
import { getAccountId } from '../account/session';
|
||||
import {
|
||||
getApiBaseURL,
|
||||
getAppPlatform,
|
||||
getAppVersion,
|
||||
getProductName,
|
||||
getSegmentWriteKey,
|
||||
} from '../common/constants';
|
||||
import * as models from '../models/index';
|
||||
import { axiosRequest } from './network/axios-request';
|
||||
import { insomniaFetch } from './insomniaFetch';
|
||||
|
||||
const analytics = new Analytics({ writeKey: getSegmentWriteKey() });
|
||||
|
||||
const getDeviceId = async () => {
|
||||
const settings = await models.settings.getOrCreate();
|
||||
const settings = await models.settings.get();
|
||||
return settings.deviceId || (await models.settings.update(settings, { deviceId: uuidv4() })).deviceId;
|
||||
};
|
||||
|
||||
@@ -49,7 +48,7 @@ export async function trackSegmentEvent(
|
||||
event: SegmentEvent,
|
||||
properties?: Record<string, any>,
|
||||
) {
|
||||
const settings = await models.settings.getOrCreate();
|
||||
const settings = await models.settings.get();
|
||||
const allowAnalytics = settings.enableAnalytics || session.isLoggedIn();
|
||||
if (allowAnalytics) {
|
||||
try {
|
||||
@@ -77,7 +76,7 @@ export async function trackSegmentEvent(
|
||||
}
|
||||
|
||||
export async function trackPageView(name: string) {
|
||||
const settings = await models.settings.getOrCreate();
|
||||
const settings = await models.settings.get();
|
||||
const allowAnalytics = settings.enableAnalytics || session.isLoggedIn();
|
||||
if (allowAnalytics) {
|
||||
try {
|
||||
@@ -101,12 +100,10 @@ export async function trackPageView(name: string) {
|
||||
|
||||
export async function sendTelemetry() {
|
||||
if (session.isLoggedIn()) {
|
||||
axiosRequest({
|
||||
insomniaFetch({
|
||||
method: 'POST',
|
||||
url: `${getApiBaseURL()}/v1/telemetry/`,
|
||||
headers: {
|
||||
'X-Session-Id': session.getCurrentSessionId(),
|
||||
},
|
||||
path: '/v1/telemetry/',
|
||||
sessionId: session.getCurrentSessionId(),
|
||||
}).catch((error: unknown) => {
|
||||
console.warn('[analytics] Unexpected error while sending telemetry', error);
|
||||
});
|
||||
|
||||
@@ -0,0 +1,30 @@
|
||||
import { app, net, protocol } from 'electron';
|
||||
|
||||
import { getApiBaseURL } from '../common/constants';
|
||||
export interface RegisterProtocolOptions {
|
||||
scheme: string;
|
||||
}
|
||||
|
||||
const scheme = 'insomnia-event-source';
|
||||
|
||||
export async function registerInsomniaStreamProtocol() {
|
||||
protocol.registerSchemesAsPrivileged([{
|
||||
scheme,
|
||||
privileges: { secure: true, standard: true, supportFetchAPI: true },
|
||||
}]);
|
||||
|
||||
await app.whenReady();
|
||||
|
||||
if (protocol.isProtocolHandled(scheme)) {
|
||||
return;
|
||||
}
|
||||
|
||||
protocol.handle(scheme, async function(request) {
|
||||
const apiURL = getApiBaseURL();
|
||||
const url = new URL(`${apiURL}/${request.url.replace(`${scheme}://`, '')}`);
|
||||
const sessionId = new URLSearchParams(url.search).get('sessionId');
|
||||
request.headers.append('X-Session-Id', sessionId || '');
|
||||
|
||||
return net.fetch(url.toString(), request);
|
||||
});
|
||||
}
|
||||
@@ -34,7 +34,7 @@ export function authorizeUserInWindow({
|
||||
// Fetch user setting to determine whether to validate SSL certificates during auth
|
||||
const {
|
||||
validateAuthSSL,
|
||||
} = await models.settings.getOrCreate();
|
||||
} = await models.settings.get();
|
||||
|
||||
// Create a child window
|
||||
const child = new BrowserWindow({
|
||||
|
||||
@@ -11,7 +11,7 @@ import { insomniaFetch } from './insomniaFetch';
|
||||
|
||||
export async function backupIfNewerVersionAvailable() {
|
||||
try {
|
||||
const settings = await models.settings.getOrCreate();
|
||||
const settings = await models.settings.get();
|
||||
console.log('[main] Checking for newer version than ', version);
|
||||
const response = await insomniaFetch<{ url: string }>({
|
||||
method: 'GET',
|
||||
|
||||
@@ -4,7 +4,7 @@ import { getApiBaseURL, getClientString } from '../common/constants';
|
||||
import { delay } from '../common/misc';
|
||||
|
||||
interface FetchConfig {
|
||||
method: 'POST' | 'PUT' | 'GET';
|
||||
method: 'POST' | 'PUT' | 'GET' | 'DELETE' | 'PATCH';
|
||||
path: string;
|
||||
sessionId: string | null;
|
||||
data?: unknown;
|
||||
@@ -26,10 +26,13 @@ const exponentialBackOff = async (url: string, init: RequestInit, retries = 0):
|
||||
const response = await net.fetch(url, init);
|
||||
if (response.status === 502 && retries < 5) {
|
||||
retries++;
|
||||
await delay(retries * 200);
|
||||
await delay(retries * 1000);
|
||||
console.log(`Received 502 from ${url} retrying`);
|
||||
return exponentialBackOff(url, init, retries);
|
||||
}
|
||||
if (!response.ok) {
|
||||
// TODO: review error status code behaviour with backend, should we parse errors here and return response
|
||||
// or should we rethrow an error with a response object inside? should we be exposing errors to the app UI?
|
||||
console.log(`Response not OK: ${response.status} for ${url}`);
|
||||
}
|
||||
return response;
|
||||
@@ -38,7 +41,7 @@ const exponentialBackOff = async (url: string, init: RequestInit, retries = 0):
|
||||
}
|
||||
};
|
||||
|
||||
export async function insomniaFetch<T = any>({ method, path, data, sessionId, origin }: FetchConfig): Promise<T> {
|
||||
export async function insomniaFetch<T = void>({ method, path, data, sessionId, origin }: FetchConfig): Promise<T> {
|
||||
const config: RequestInit = {
|
||||
method,
|
||||
headers: {
|
||||
@@ -51,13 +54,15 @@ export async function insomniaFetch<T = any>({ method, path, data, sessionId, or
|
||||
if (sessionId === undefined) {
|
||||
throw new Error(`No session ID provided to ${method}:${path}`);
|
||||
}
|
||||
const response = await exponentialBackOff(`${origin || getApiBaseURL()}${path}`, config);
|
||||
|
||||
const apiURL = getApiBaseURL();
|
||||
const response = await exponentialBackOff(`${origin || apiURL}${path}`, config);
|
||||
const uri = response.headers.get('x-insomnia-command');
|
||||
if (uri) {
|
||||
for (const window of BrowserWindow.getAllWindows()) {
|
||||
window.webContents.send('shell:open', uri);
|
||||
}
|
||||
}
|
||||
const isJson = response.headers.get('content-type') === 'application/json' || path.match(/\.json$/);
|
||||
const isJson = response.headers.get('content-type')?.includes('application/json') || path.match(/\.json$/);
|
||||
return isJson ? response.json() : response.text();
|
||||
}
|
||||
@@ -15,7 +15,7 @@ interface AxiosRequestMockUserSettings {
|
||||
}
|
||||
|
||||
jest.mock('axios');
|
||||
jest.spyOn(models.settings, 'getOrCreate');
|
||||
jest.spyOn(models.settings, 'get');
|
||||
|
||||
describe('axiosRequest used for git-sync', () => {
|
||||
beforeEach(globalBeforeEach);
|
||||
@@ -46,7 +46,7 @@ describe('axiosRequest used for git-sync', () => {
|
||||
noProxy: '',
|
||||
validateSSL: false,
|
||||
};
|
||||
(models.settings.getOrCreate as unknown as jest.Mock).mockImplementation(() => mockInsomniaConfigPanelUserSettings);
|
||||
(models.settings.get as unknown as jest.Mock).mockImplementation(() => mockInsomniaConfigPanelUserSettings);
|
||||
const response = await axiosRequest({ url: 'https://git.acme.com/username/repo-name.git/git-upload-pack' });
|
||||
expect(response.config.proxy).toBe(false);
|
||||
});
|
||||
@@ -59,7 +59,7 @@ describe('axiosRequest used for git-sync', () => {
|
||||
noProxy: 'localhost,127.0.0.1',
|
||||
validateSSL: false,
|
||||
};
|
||||
(models.settings.getOrCreate as unknown as jest.Mock).mockImplementation(() => mockInsomniaConfigPanelUserSettings);
|
||||
(models.settings.get as unknown as jest.Mock).mockImplementation(() => mockInsomniaConfigPanelUserSettings);
|
||||
const response = await axiosRequest({ url: 'http://git.acme.com/username/repo-name.git/git-upload-pack' });
|
||||
expect(response.config.proxy).toEqual({ host: 'some.proxy.com', port: 8080 });
|
||||
});
|
||||
@@ -72,7 +72,7 @@ describe('axiosRequest used for git-sync', () => {
|
||||
noProxy: 'localhost,127.0.0.1',
|
||||
validateSSL: false,
|
||||
};
|
||||
(models.settings.getOrCreate as unknown as jest.Mock).mockImplementation(() => mockInsomniaConfigPanelUserSettings);
|
||||
(models.settings.get as unknown as jest.Mock).mockImplementation(() => mockInsomniaConfigPanelUserSettings);
|
||||
const response = await axiosRequest({ url: 'http://git.acme.com/username/repo-name.git/git-upload-pack' });
|
||||
expect(response.config.proxy).toBe(false);
|
||||
});
|
||||
@@ -85,7 +85,7 @@ describe('axiosRequest used for git-sync', () => {
|
||||
noProxy: 'localhost,127.0.0.1',
|
||||
validateSSL: false,
|
||||
};
|
||||
(models.settings.getOrCreate as unknown as jest.Mock).mockImplementation(() => mockInsomniaConfigPanelUserSettings);
|
||||
(models.settings.get as unknown as jest.Mock).mockImplementation(() => mockInsomniaConfigPanelUserSettings);
|
||||
const response = await axiosRequest({ url: 'https://git.acme.com/username/repo-name.git/git-upload-pack' });
|
||||
expect(response.config.proxy).toEqual({ host: 'some.proxy.com', port: 8080 });
|
||||
});
|
||||
@@ -98,7 +98,7 @@ describe('axiosRequest used for git-sync', () => {
|
||||
noProxy: 'localhost,127.0.0.1',
|
||||
validateSSL: false,
|
||||
};
|
||||
(models.settings.getOrCreate as unknown as jest.Mock).mockImplementation(() => mockInsomniaConfigPanelUserSettings);
|
||||
(models.settings.get as unknown as jest.Mock).mockImplementation(() => mockInsomniaConfigPanelUserSettings);
|
||||
const response = await axiosRequest({ url: 'http://git.acme.com/username/repo-name.git/git-upload-pack' });
|
||||
expect(response.config.proxy).toEqual({ host: 'some.proxy.com', port: 8081 });
|
||||
});
|
||||
@@ -111,7 +111,7 @@ describe('axiosRequest used for git-sync', () => {
|
||||
noProxy: 'localhost,127.0.0.1',
|
||||
validateSSL: false,
|
||||
};
|
||||
(models.settings.getOrCreate as unknown as jest.Mock).mockImplementation(() => mockInsomniaConfigPanelUserSettings);
|
||||
(models.settings.get as unknown as jest.Mock).mockImplementation(() => mockInsomniaConfigPanelUserSettings);
|
||||
const response = await axiosRequest({ url: 'https://git.acme.com/username/repo-name.git/git-upload-pack' });
|
||||
expect(response.config.proxy).toEqual({ host: 'some.proxy.com', port: 8080 });
|
||||
});
|
||||
|
||||
@@ -7,7 +7,7 @@ import * as models from '../../models';
|
||||
import { isUrlMatchedInNoProxyRule } from '../../network/is-url-matched-in-no-proxy-rule';
|
||||
import { setDefaultProtocol } from '../../utils/url/protocol';
|
||||
export const axiosRequest = async (config: AxiosRequestConfig): Promise<AxiosResponse> => {
|
||||
const settings = await models.settings.getOrCreate();
|
||||
const settings = await models.settings.get();
|
||||
const isHttps = config.url?.indexOf('https:') === 0;
|
||||
let proxyUrl: string | null = null;
|
||||
|
||||
|
||||
@@ -133,7 +133,7 @@ const openCurlConnection = async (
|
||||
}
|
||||
const readyStateChannel = `curl.${request._id}.readyState`;
|
||||
|
||||
const settings = await models.settings.getOrCreate();
|
||||
const settings = await models.settings.get();
|
||||
const start = performance.now();
|
||||
const clientCertificates = await models.clientCertificate.findByParentId(options.workspaceId);
|
||||
const filteredClientCertificates = clientCertificates.filter(c => !c.disabled && urlMatchesCertHost(setDefaultProtocol(c.host, 'https:'), options.url));
|
||||
@@ -223,7 +223,7 @@ const openCurlConnection = async (
|
||||
settingStoreCookies: request.settingStoreCookies,
|
||||
bodyCompression: null,
|
||||
};
|
||||
const settings = await models.settings.getOrCreate();
|
||||
const settings = await models.settings.get();
|
||||
const res = await models.response.create(responsePatch, settings.maxHistoryResponses);
|
||||
models.requestMeta.updateOrCreateByParentId(request._id, { activeResponseId: res._id });
|
||||
|
||||
@@ -271,7 +271,7 @@ const openCurlConnection = async (
|
||||
};
|
||||
|
||||
const createErrorResponse = async (responseId: string, requestId: string, environmentId: string | null, timelinePath: string, message: string) => {
|
||||
const settings = await models.settings.getOrCreate();
|
||||
const settings = await models.settings.get();
|
||||
const responsePatch = {
|
||||
_id: responseId,
|
||||
parentId: requestId,
|
||||
|
||||
@@ -179,7 +179,7 @@ const openWebSocketConnection = async (
|
||||
const lowerCasedEnabledHeaders = headers
|
||||
.filter(({ name, disabled }) => Boolean(name) && !disabled)
|
||||
.reduce(reduceArrayToLowerCaseKeyedDictionary, {});
|
||||
const settings = await models.settings.getOrCreate();
|
||||
const settings = await models.settings.get();
|
||||
const start = performance.now();
|
||||
|
||||
const clientCertificates = await models.clientCertificate.findByParentId(options.workspaceId);
|
||||
@@ -254,7 +254,7 @@ const openWebSocketConnection = async (
|
||||
settingStoreCookies: request.settingStoreCookies,
|
||||
};
|
||||
|
||||
const settings = await models.settings.getOrCreate();
|
||||
const settings = await models.settings.get();
|
||||
const res = await models.webSocketResponse.create(responsePatch, settings.maxHistoryResponses);
|
||||
models.requestMeta.updateOrCreateByParentId(request._id, { activeResponseId: res._id });
|
||||
|
||||
@@ -298,7 +298,7 @@ const openWebSocketConnection = async (
|
||||
settingSendCookies: request.settingSendCookies,
|
||||
settingStoreCookies: request.settingStoreCookies,
|
||||
};
|
||||
const settings = await models.settings.getOrCreate();
|
||||
const settings = await models.settings.get();
|
||||
const res = await models.webSocketResponse.create(responsePatch, settings.maxHistoryResponses);
|
||||
models.requestMeta.updateOrCreateByParentId(request._id, { activeResponseId: res._id });
|
||||
deleteRequestMaps(request._id, `Unexpected response ${incomingMessage.statusCode}`);
|
||||
@@ -383,7 +383,7 @@ const openWebSocketConnection = async (
|
||||
};
|
||||
|
||||
const createErrorResponse = async (responseId: string, requestId: string, environmentId: string | null, timelinePath: string, message: string) => {
|
||||
const settings = await models.settings.getOrCreate();
|
||||
const settings = await models.settings.get();
|
||||
const responsePatch = {
|
||||
_id: responseId,
|
||||
parentId: requestId,
|
||||
|
||||
@@ -13,7 +13,7 @@ let enabled = false;
|
||||
* Watch setting for changes. This must be called after the DB is initialized.
|
||||
*/
|
||||
export function sentryWatchAnalyticsEnabled() {
|
||||
models.settings.getOrCreate().then(settings => {
|
||||
models.settings.get().then(settings => {
|
||||
enabled = settings.enableAnalytics || session.isLoggedIn();
|
||||
});
|
||||
|
||||
|
||||
@@ -79,14 +79,14 @@ export const init = async () => {
|
||||
if (isUpdateSupported()) {
|
||||
// perhaps disable this method of upgrading just incase it trigger before backup is complete
|
||||
// on app start
|
||||
const settings = await models.settings.getOrCreate();
|
||||
const settings = await models.settings.get();
|
||||
const updateUrl = getUpdateUrl(settings.updateChannel);
|
||||
if (settings.updateAutomatically && updateUrl) {
|
||||
_checkForUpdates(updateUrl);
|
||||
}
|
||||
// on an interval (3h)
|
||||
setInterval(async () => {
|
||||
const settings = await models.settings.getOrCreate();
|
||||
const settings = await models.settings.get();
|
||||
const updateUrl = getUpdateUrl(settings.updateChannel);
|
||||
if (settings.updateAutomatically && updateUrl) {
|
||||
_checkForUpdates(updateUrl);
|
||||
@@ -96,7 +96,7 @@ export const init = async () => {
|
||||
// on check now button pushed
|
||||
ipcMain.on('manualUpdateCheck', async () => {
|
||||
console.log('[updater] Manual update check');
|
||||
const settings = await models.settings.getOrCreate();
|
||||
const settings = await models.settings.get();
|
||||
const updateUrl = isUpdateSupported() && getUpdateUrl(settings.updateChannel);
|
||||
if (!updateUrl) {
|
||||
_sendUpdateStatus('Updates Not Supported');
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
import * as crypto from 'crypto';
|
||||
|
||||
import { database as db } from '../common/database';
|
||||
import type { BaseModel } from './index';
|
||||
import { type BaseModel } from './index';
|
||||
|
||||
export const name = 'Environment';
|
||||
export const type = 'Environment';
|
||||
@@ -70,13 +70,26 @@ export async function getOrCreateForParentId(parentId: string) {
|
||||
});
|
||||
|
||||
if (!environments.length) {
|
||||
return create({
|
||||
parentId,
|
||||
name: 'Base Environment',
|
||||
// Deterministic base env ID. It helps reduce sync complexity since we won't have to
|
||||
// de-duplicate environments.
|
||||
_id: `${prefix}_${crypto.createHash('sha1').update(parentId).digest('hex')}`,
|
||||
});
|
||||
// Deterministic base env ID. It helps reduce sync complexity since we won't have to
|
||||
// de-duplicate environments.
|
||||
const baseEnvironmentId = `${prefix}_${crypto.createHash('sha1').update(parentId).digest('hex')}`;
|
||||
try {
|
||||
const baseEnvironment = await create({
|
||||
parentId,
|
||||
name: 'Base Environment',
|
||||
_id: baseEnvironmentId,
|
||||
});
|
||||
|
||||
return baseEnvironment;
|
||||
} catch (e) {
|
||||
const existingEnvironment = await getById(baseEnvironmentId);
|
||||
|
||||
if (existingEnvironment) {
|
||||
return existingEnvironment;
|
||||
}
|
||||
|
||||
throw e;
|
||||
}
|
||||
}
|
||||
|
||||
return environments[environments.length - 1];
|
||||
|
||||
@@ -1,12 +1,8 @@
|
||||
import { describe, expect, it } from '@jest/globals';
|
||||
|
||||
import { DEFAULT_PROJECT_ID } from '../../project';
|
||||
import { sortProjects } from '../project';
|
||||
|
||||
const defaultProject = { name: 'a', remoteId: null, _id: DEFAULT_PROJECT_ID };
|
||||
|
||||
const localA = { name: 'a', remoteId: null, _id: 'localA' };
|
||||
const localB = { name: 'b', remoteId: null, _id: 'localB' };
|
||||
const defaultOrgProject = { name: 'a', remoteId: 'proj_team_123456789345678987654', _id: 'not important' };
|
||||
|
||||
const remoteA = { name: 'a', remoteId: 'notNull', _id: 'remoteA' };
|
||||
const remoteB = { name: 'b', remoteId: 'notNull', _id: 'remoteB' };
|
||||
@@ -16,18 +12,14 @@ describe('sortProjects', () => {
|
||||
it('sorts projects by default > local > remote > name', () => {
|
||||
const unSortedProjects = [
|
||||
remoteA,
|
||||
localB,
|
||||
defaultProject,
|
||||
defaultOrgProject,
|
||||
remoteB,
|
||||
localA,
|
||||
remote0,
|
||||
];
|
||||
const result = sortProjects(unSortedProjects);
|
||||
|
||||
const sortedProjects = [
|
||||
defaultProject,
|
||||
localA,
|
||||
localB,
|
||||
defaultOrgProject,
|
||||
remote0,
|
||||
remoteA,
|
||||
remoteB,
|
||||
|
||||
@@ -1,8 +1,7 @@
|
||||
import { isDefaultProject, isLocalProject, isRemoteProject, Project } from '../project';
|
||||
import { isDefaultOrganizationProject, Project } from '../project';
|
||||
export const sortProjects = (projects: Project[]) => [
|
||||
...projects.filter(isDefaultProject),
|
||||
...projects.filter(p => isLocalProject(p) && !isDefaultProject(p))
|
||||
...projects.filter(p => isDefaultOrganizationProject(p))
|
||||
.sort((a, b) => a.name.localeCompare(b.name)),
|
||||
...projects.filter(isRemoteProject)
|
||||
...projects.filter(p => !isDefaultOrganizationProject(p))
|
||||
.sort((a, b) => a.name.localeCompare(b.name)),
|
||||
];
|
||||
@@ -1,17 +1,30 @@
|
||||
|
||||
export const type = 'Organization';
|
||||
export const prefix = 'org';
|
||||
|
||||
export interface Organization {
|
||||
_id: string;
|
||||
name: string;
|
||||
interface Branding {
|
||||
logo_url: string;
|
||||
}
|
||||
|
||||
export const DEFAULT_ORGANIZATION_ID = `${prefix}_default-project`;
|
||||
export interface Metadata {
|
||||
organizationType: string;
|
||||
ownerAccountId: string;
|
||||
}
|
||||
|
||||
export const defaultOrganization: Organization = {
|
||||
_id: DEFAULT_ORGANIZATION_ID,
|
||||
name: 'Personal Projects',
|
||||
};
|
||||
export interface Organization {
|
||||
id: string;
|
||||
name: string;
|
||||
display_name: string;
|
||||
branding?: Branding;
|
||||
metadata: Metadata;
|
||||
}
|
||||
export const SCRATCHPAD_ORGANIZATION_ID = 'org_scratchpad';
|
||||
export const isScratchpadOrganizationId = (organizationId: string) =>
|
||||
organizationId === SCRATCHPAD_ORGANIZATION_ID;
|
||||
export const isPersonalOrganization = (organization: Organization) =>
|
||||
organization.metadata.organizationType === 'personal';
|
||||
|
||||
export const isDefaultOrganization = (organization: Organization) => organization._id === DEFAULT_ORGANIZATION_ID;
|
||||
export const isOwnerOfOrganization = ({
|
||||
organization,
|
||||
accountId,
|
||||
}: {
|
||||
organization: Organization;
|
||||
accountId: string;
|
||||
}) =>
|
||||
organization.metadata.ownerAccountId === accountId;
|
||||
@@ -1,6 +1,6 @@
|
||||
import { database as db } from '../common/database';
|
||||
import { generateId } from '../common/misc';
|
||||
import type { BaseModel } from './index';
|
||||
import { type BaseModel } from './index';
|
||||
|
||||
export const name = 'Project';
|
||||
export const type = 'Project';
|
||||
@@ -8,13 +8,12 @@ export const prefix = 'proj';
|
||||
export const canDuplicate = false;
|
||||
export const canSync = false;
|
||||
|
||||
export const DEFAULT_PROJECT_ID = `${prefix}_default-project`;
|
||||
export const SCRATCHPAD_PROJECT_ID = `${prefix}_scratchpad`;
|
||||
|
||||
export const isDefaultProject = (project: Pick<Project, '_id'>) => project._id === DEFAULT_PROJECT_ID;
|
||||
export const isNotDefaultProject = (project: Pick<Project, '_id'>) => !isDefaultProject(project);
|
||||
export const isScratchpadProject = (project: Pick<Project, '_id'>) => project._id === SCRATCHPAD_PROJECT_ID;
|
||||
export const isLocalProject = (project: Pick<Project, 'remoteId'>): project is LocalProject => project.remoteId === null;
|
||||
export const isRemoteProject = (project: Pick<Project, 'remoteId'>): project is RemoteProject => !isLocalProject(project);
|
||||
export const projectHasSettings = (project: Pick<Project, '_id'>) => !isDefaultProject(project);
|
||||
export const projectHasSettings = (project: Pick<Project, '_id'>) => !isScratchpadProject(project);
|
||||
|
||||
interface CommonProject {
|
||||
name: string;
|
||||
@@ -77,3 +76,9 @@ export async function all() {
|
||||
const projects = await db.all<Project>(type);
|
||||
return projects;
|
||||
}
|
||||
|
||||
export function isDefaultOrganizationProject(project: Project) {
|
||||
// legacy remoteId = proj_team_xxx
|
||||
// new remoteId = proj_org_xxx
|
||||
return project.remoteId?.startsWith('proj_team') || project.remoteId?.startsWith('proj_org');
|
||||
}
|
||||
@@ -118,7 +118,7 @@ export async function all() {
|
||||
}
|
||||
|
||||
export async function removeForRequest(parentId: string, environmentId?: string | null) {
|
||||
const settings = await models.settings.getOrCreate();
|
||||
const settings = await models.settings.get();
|
||||
const query: Record<string, any> = {
|
||||
parentId,
|
||||
};
|
||||
@@ -149,7 +149,7 @@ async function _findRecentForRequest(
|
||||
};
|
||||
|
||||
// Filter responses by environment if setting is enabled
|
||||
if ((await models.settings.getOrCreate()).filterResponsesByEnv) {
|
||||
if ((await models.settings.get()).filterResponsesByEnv) {
|
||||
query.environmentId = environmentId;
|
||||
}
|
||||
|
||||
@@ -177,7 +177,7 @@ export async function create(patch: Partial<Response> = {}, maxResponses = 20):
|
||||
const requestVersion = request ? await models.requestVersion.create(request) : null;
|
||||
patch.requestVersionId = requestVersion ? requestVersion._id : null;
|
||||
// Filter responses by environment if setting is enabled
|
||||
const shouldQueryByEnvId = (await models.settings.getOrCreate()).filterResponsesByEnv && patch.hasOwnProperty('environmentId');
|
||||
const shouldQueryByEnvId = (await models.settings.get()).filterResponsesByEnv && patch.hasOwnProperty('environmentId');
|
||||
const query = {
|
||||
parentId,
|
||||
...(shouldQueryByEnvId ? { environmentId: patch.environmentId } : {}),
|
||||
|
||||
@@ -117,6 +117,12 @@ export async function getOrCreate() {
|
||||
return results[0];
|
||||
}
|
||||
|
||||
export async function get() {
|
||||
const results = await db.all<Settings>(type) || [];
|
||||
|
||||
return results[0];
|
||||
}
|
||||
|
||||
/**
|
||||
* Ensure map is updated when new hotkeys are added
|
||||
*/
|
||||
|
||||
@@ -91,7 +91,7 @@ export async function all() {
|
||||
}
|
||||
|
||||
export async function removeForRequest(parentId: string, environmentId?: string | null) {
|
||||
const settings = await models.settings.getOrCreate();
|
||||
const settings = await models.settings.get();
|
||||
const query: Record<string, any> = {
|
||||
parentId,
|
||||
};
|
||||
@@ -128,7 +128,7 @@ export async function create(patch: Partial<WebSocketResponse> = {}, maxResponse
|
||||
};
|
||||
|
||||
if (
|
||||
(await models.settings.getOrCreate()).filterResponsesByEnv &&
|
||||
(await models.settings.get()).filterResponsesByEnv &&
|
||||
patch.hasOwnProperty('environmentId')
|
||||
) {
|
||||
query.environmentId = patch.environmentId;
|
||||
@@ -158,7 +158,7 @@ async function _findRecentForRequest(
|
||||
};
|
||||
|
||||
// Filter responses by environment if setting is enabled
|
||||
if ((await models.settings.getOrCreate()).filterResponsesByEnv) {
|
||||
if ((await models.settings.get()).filterResponsesByEnv) {
|
||||
query.environmentId = environmentId;
|
||||
}
|
||||
|
||||
|
||||
@@ -4,7 +4,7 @@ import { database as db } from '../common/database';
|
||||
import { strings } from '../common/strings';
|
||||
import type { BaseModel } from './index';
|
||||
import * as models from './index';
|
||||
import { DEFAULT_PROJECT_ID, isProjectId } from './project';
|
||||
import { isProjectId } from './project';
|
||||
|
||||
export const name = 'Workspace';
|
||||
export const type = 'Workspace';
|
||||
@@ -51,7 +51,6 @@ export function migrate(doc: Workspace) {
|
||||
doc = _migrateExtractClientCertificates(doc);
|
||||
doc = _migrateEnsureName(doc);
|
||||
doc = _migrateScope(doc);
|
||||
doc = _migrateIntoDefaultProject(doc);
|
||||
return doc;
|
||||
} catch (e) {
|
||||
console.log('[db] Error during workspace migration', e);
|
||||
@@ -147,17 +146,14 @@ function _migrateScope(workspace: MigrationWorkspace) {
|
||||
return workspace as Workspace;
|
||||
}
|
||||
|
||||
function _migrateIntoDefaultProject(workspace: Workspace) {
|
||||
if (!workspace.parentId) {
|
||||
console.log(`[db] No workspace parentId found for ${workspace._id} setting default ${DEFAULT_PROJECT_ID}`);
|
||||
workspace.parentId = DEFAULT_PROJECT_ID;
|
||||
}
|
||||
|
||||
return workspace;
|
||||
}
|
||||
|
||||
function expectParentToBeProject(parentId?: string | null) {
|
||||
if (parentId && !isProjectId(parentId)) {
|
||||
throw new Error('Expected the parent of a Workspace to be a Project');
|
||||
}
|
||||
}
|
||||
|
||||
export const SCRATCHPAD_WORKSPACE_ID = 'wrk_scratchpad';
|
||||
|
||||
export function isScratchpad(workspace: Workspace) {
|
||||
return workspace._id === SCRATCHPAD_WORKSPACE_ID;
|
||||
}
|
||||
@@ -56,7 +56,7 @@ export const fetchRequestData = async (requestId: string) => {
|
||||
const environment = activeEnvironment || await models.environment.getOrCreateForParentId(workspace._id);
|
||||
invariant(environment, 'failed to find environment ' + activeEnvironmentId);
|
||||
|
||||
const settings = await models.settings.getOrCreate();
|
||||
const settings = await models.settings.get();
|
||||
invariant(settings, 'failed to create settings');
|
||||
const clientCertificates = await models.clientCertificate.findByParentId(workspaceId);
|
||||
const caCert = await models.caCertificate.findByParentId(workspaceId);
|
||||
|
||||
@@ -6,7 +6,7 @@ import { globalBeforeEach } from '../../../__jest__/before-each';
|
||||
import { getAppVersion } from '../../../common/constants';
|
||||
import { database as db } from '../../../common/database';
|
||||
import * as models from '../../../models/index';
|
||||
import { DEFAULT_PROJECT_ID, Project } from '../../../models/project';
|
||||
import { Project } from '../../../models/project';
|
||||
import { WorkspaceScopeKeys } from '../../../models/workspace';
|
||||
import * as plugin from '../data';
|
||||
|
||||
@@ -16,7 +16,8 @@ describe('init()', () => {
|
||||
beforeEach(globalBeforeEach);
|
||||
|
||||
it('initializes correctly', async () => {
|
||||
const { data } = plugin.init(DEFAULT_PROJECT_ID);
|
||||
const project = await models.project.create();
|
||||
const { data } = plugin.init(project._id);
|
||||
expect(Object.keys(data)).toEqual(['import', 'export']);
|
||||
expect(Object.keys(data.export).sort()).toEqual(['har', 'insomnia']);
|
||||
expect(Object.keys(data.import).sort()).toEqual(['raw', 'uri']);
|
||||
@@ -35,6 +36,7 @@ describe('app.import.*', () => {
|
||||
modified: 222,
|
||||
parentId: project._id,
|
||||
});
|
||||
await models.settings.getOrCreate();
|
||||
});
|
||||
|
||||
it('uri', async () => {
|
||||
@@ -135,6 +137,7 @@ describe('app.export.*', () => {
|
||||
beforeEach(async () => {
|
||||
await globalBeforeEach();
|
||||
project = await models.project.create();
|
||||
await models.settings.getOrCreate();
|
||||
await models.workspace.create({
|
||||
_id: 'wrk_1',
|
||||
created: 111,
|
||||
|
||||
@@ -184,7 +184,7 @@ export async function getPlugins(force = false): Promise<Plugin[]> {
|
||||
}
|
||||
|
||||
if (!plugins) {
|
||||
const settings = await models.settings.getOrCreate();
|
||||
const settings = await models.settings.get();
|
||||
const allConfigs: PluginConfigMap = settings.pluginConfig;
|
||||
const extraPaths = settings.pluginPath
|
||||
.split(':')
|
||||
|
||||
@@ -4,7 +4,7 @@ const sidebarBackground = {
|
||||
notice: '#f0e137',
|
||||
warning: '#ff9a1f',
|
||||
danger: '#ff5631',
|
||||
surprise: '#a896ff',
|
||||
surprise: '#4000BF',
|
||||
info: '#46c1e6',
|
||||
};
|
||||
|
||||
@@ -62,7 +62,7 @@ export default {
|
||||
notice: '#d8c84d',
|
||||
warning: '#ec8702',
|
||||
danger: '#e15251',
|
||||
surprise: '#8776d5',
|
||||
surprise: '#4000BF',
|
||||
info: '#20aed9',
|
||||
},
|
||||
},
|
||||
|
||||
@@ -7,7 +7,6 @@ import { globalBeforeEach } from '../../../__jest__/before-each';
|
||||
import { database as db } from '../../../common/database';
|
||||
import * as models from '../../../models';
|
||||
import { workspaceModelSchema } from '../../../models/__schemas__/model-schemas';
|
||||
import { DEFAULT_PROJECT_ID } from '../../../models/project';
|
||||
import { GIT_CLONE_DIR, GIT_INSOMNIA_DIR, GIT_INSOMNIA_DIR_NAME } from '../git-vcs';
|
||||
import { NeDBClient } from '../ne-db-client';
|
||||
import { assertAsyncError, setupDateMocks } from './util';
|
||||
@@ -21,9 +20,12 @@ describe('NeDBClient', () => {
|
||||
workspaceBuilder.reset();
|
||||
setupDateMocks();
|
||||
// Create some sample models
|
||||
await models.project.all();
|
||||
await models.project.create({
|
||||
_id: 'proj_1',
|
||||
});
|
||||
await models.workspace.create({
|
||||
_id: 'wrk_1',
|
||||
parentId: 'proj_1',
|
||||
});
|
||||
await models.request.create({
|
||||
_id: 'req_1',
|
||||
@@ -43,7 +45,7 @@ describe('NeDBClient', () => {
|
||||
|
||||
describe('readdir()', () => {
|
||||
it('reads model IDs from model type folders', async () => {
|
||||
const neDbClient = new NeDBClient('wrk_1', DEFAULT_PROJECT_ID);
|
||||
const neDbClient = new NeDBClient('wrk_1', 'proj_1');
|
||||
const reqDir = path.join(GIT_INSOMNIA_DIR, models.request.type);
|
||||
const wrkDir = path.join(GIT_INSOMNIA_DIR, models.workspace.type);
|
||||
expect(await neDbClient.readdir(GIT_CLONE_DIR)).toEqual([GIT_INSOMNIA_DIR_NAME]);
|
||||
@@ -71,7 +73,7 @@ describe('NeDBClient', () => {
|
||||
const wrk1Yml = path.join(GIT_INSOMNIA_DIR, models.workspace.type, 'wrk_1.yml');
|
||||
const req1Yml = path.join(GIT_INSOMNIA_DIR, models.request.type, 'req_1.yml');
|
||||
const reqXYml = path.join(GIT_INSOMNIA_DIR, models.request.type, 'req_x.yml');
|
||||
const pNeDB = new NeDBClient('wrk_1', DEFAULT_PROJECT_ID);
|
||||
const pNeDB = new NeDBClient('wrk_1', 'proj_1');
|
||||
expect(YAML.parse((await pNeDB.readFile(wrk1Yml, 'utf8')).toString())).toEqual(
|
||||
expect.objectContaining({
|
||||
_id: 'wrk_1',
|
||||
@@ -100,7 +102,7 @@ describe('NeDBClient', () => {
|
||||
type: 'file',
|
||||
});
|
||||
// Act
|
||||
const neDbClient = new NeDBClient('wrk_1', DEFAULT_PROJECT_ID);
|
||||
const neDbClient = new NeDBClient('wrk_1', 'proj_1');
|
||||
// Assert
|
||||
expect(await neDbClient.stat(GIT_CLONE_DIR)).toEqual(dirType);
|
||||
expect(await neDbClient.stat(GIT_INSOMNIA_DIR)).toEqual(dirType);
|
||||
@@ -115,7 +117,7 @@ describe('NeDBClient', () => {
|
||||
// Arrange
|
||||
const upsertSpy = jest.spyOn(db, 'upsert');
|
||||
const workspaceId = 'wrk_1';
|
||||
const neDbClient = new NeDBClient(workspaceId, DEFAULT_PROJECT_ID);
|
||||
const neDbClient = new NeDBClient(workspaceId, 'proj_1');
|
||||
const env = {
|
||||
_id: 'env_1',
|
||||
type: models.environment.type,
|
||||
@@ -133,7 +135,7 @@ describe('NeDBClient', () => {
|
||||
it('should write files in GIT_INSOMNIA_DIR directory to db', async () => {
|
||||
// Arrange
|
||||
const workspaceId = 'wrk_1';
|
||||
const neDbClient = new NeDBClient(workspaceId, DEFAULT_PROJECT_ID);
|
||||
const neDbClient = new NeDBClient(workspaceId, 'proj_1');
|
||||
const upsertSpy = jest.spyOn(db, 'upsert');
|
||||
const env = {
|
||||
_id: 'env_1',
|
||||
@@ -180,7 +182,7 @@ describe('NeDBClient', () => {
|
||||
it('should throw error if id does not match', async () => {
|
||||
// Arrange
|
||||
const workspaceId = 'wrk_1';
|
||||
const neDbClient = new NeDBClient(workspaceId, DEFAULT_PROJECT_ID);
|
||||
const neDbClient = new NeDBClient(workspaceId, 'proj_1');
|
||||
const env = {
|
||||
_id: 'env_1',
|
||||
type: models.environment.type,
|
||||
@@ -198,7 +200,7 @@ describe('NeDBClient', () => {
|
||||
it('should throw error if type does not match', async () => {
|
||||
// Arrange
|
||||
const workspaceId = 'wrk_1';
|
||||
const neDbClient = new NeDBClient(workspaceId, DEFAULT_PROJECT_ID);
|
||||
const neDbClient = new NeDBClient(workspaceId, 'proj_1');
|
||||
const env = {
|
||||
_id: 'env_1',
|
||||
type: models.environment.type,
|
||||
@@ -217,7 +219,7 @@ describe('NeDBClient', () => {
|
||||
describe('mkdir()', () => {
|
||||
it('should throw error', async () => {
|
||||
const workspaceId = 'wrk_1';
|
||||
const neDbClient = new NeDBClient(workspaceId, DEFAULT_PROJECT_ID);
|
||||
const neDbClient = new NeDBClient(workspaceId, 'proj_1');
|
||||
const promiseResult = neDbClient.mkdir();
|
||||
await expect(promiseResult).rejects.toThrowError('NeDBClient is not writable');
|
||||
});
|
||||
|
||||
@@ -4,7 +4,6 @@ import { getApiBaseURL, getAppWebsiteBaseURL, getGitHubGraphQLApiURL } from '../
|
||||
|
||||
export const GITHUB_TOKEN_STORAGE_KEY = 'github-oauth-token';
|
||||
export const GITHUB_GRAPHQL_API_URL = getGitHubGraphQLApiURL();
|
||||
const getOauthPageURL = () => getAppWebsiteBaseURL() + '/oauth/github';
|
||||
|
||||
/**
|
||||
* This cache stores the states that are generated for the OAuth flow.
|
||||
@@ -18,7 +17,7 @@ export function generateAuthorizationUrl() {
|
||||
const scopes = ['repo', 'read:user', 'user:email'];
|
||||
const scope = scopes.join(' ');
|
||||
|
||||
const url = new URL(getOauthPageURL());
|
||||
const url = new URL(getAppWebsiteBaseURL() + '/oauth/github');
|
||||
|
||||
statesCache.add(state);
|
||||
|
||||
@@ -43,8 +42,10 @@ export async function exchangeCodeForToken({
|
||||
);
|
||||
}
|
||||
|
||||
const apiURL = getApiBaseURL();
|
||||
|
||||
return window.main.axiosRequest({
|
||||
url: getApiBaseURL() + '/v1/oauth/github',
|
||||
url: apiURL + '/v1/oauth/github',
|
||||
method: 'POST',
|
||||
headers: {
|
||||
'Content-Type': 'application/json',
|
||||
|
||||
@@ -25,9 +25,10 @@ const getGitLabConfig = async () => {
|
||||
};
|
||||
}
|
||||
|
||||
const apiURL = getApiBaseURL();
|
||||
// Otherwise fetch the config for the GitLab API
|
||||
return window.main.axiosRequest({
|
||||
url: getApiBaseURL() + '/v1/oauth/gitlab/config',
|
||||
url: apiURL + '/v1/oauth/gitlab/config',
|
||||
method: 'GET',
|
||||
}).then(({ data }) => {
|
||||
return {
|
||||
|
||||
@@ -28,7 +28,7 @@ describe('initialize-backend-project', () => {
|
||||
const workspaceMeta = await models.workspaceMeta.create({ parentId: workspace._id });
|
||||
vcs.clearBackendProject();
|
||||
|
||||
await pushSnapshotOnInitialize({ vcs, project, workspace, workspaceMeta });
|
||||
await pushSnapshotOnInitialize({ vcs, project, workspace });
|
||||
|
||||
expect(pushSpy).not.toHaveBeenCalled();
|
||||
await expect(models.workspaceMeta.getByParentId(workspace._id)).resolves.toStrictEqual(workspaceMeta);
|
||||
@@ -40,7 +40,7 @@ describe('initialize-backend-project', () => {
|
||||
const workspaceMeta = await models.workspaceMeta.create({ parentId: workspace._id });
|
||||
vcs.switchAndCreateBackendProjectIfNotExist(workspace._id, workspace.name);
|
||||
|
||||
await pushSnapshotOnInitialize({ vcs, project, workspace, workspaceMeta });
|
||||
await pushSnapshotOnInitialize({ vcs, project, workspace });
|
||||
|
||||
expect(pushSpy).not.toHaveBeenCalled();
|
||||
await expect(models.workspaceMeta.getByParentId(workspace._id)).resolves.toStrictEqual(workspaceMeta);
|
||||
@@ -50,36 +50,22 @@ describe('initialize-backend-project', () => {
|
||||
const project = await models.project.create({ remoteId: 'abc' });
|
||||
const anotherProject = await models.project.create({ remoteId: 'def' });
|
||||
const workspace = await models.workspace.create({ parentId: anotherProject._id });
|
||||
const workspaceMeta = await models.workspaceMeta.create({ parentId: workspace._id });
|
||||
vcs.switchAndCreateBackendProjectIfNotExist(workspace._id, workspace.name);
|
||||
|
||||
await pushSnapshotOnInitialize({ vcs, project, workspace, workspaceMeta });
|
||||
await pushSnapshotOnInitialize({ vcs, project, workspace });
|
||||
|
||||
expect(pushSpy).not.toHaveBeenCalled();
|
||||
// await expect(models.workspaceMeta.getByParentId(workspace._id)).resolves.toStrictEqual(workspaceMeta);
|
||||
});
|
||||
|
||||
it('should not push snapshot if not marked for push', async () => {
|
||||
const project = await models.project.create({ remoteId: 'abc' });
|
||||
const workspace = await models.workspace.create({ parentId: project._id });
|
||||
const workspaceMeta = await models.workspaceMeta.create({ parentId: workspace._id, pushSnapshotOnInitialize: false });
|
||||
vcs.switchAndCreateBackendProjectIfNotExist(workspace._id, workspace.name);
|
||||
|
||||
await pushSnapshotOnInitialize({ vcs, project, workspace, workspaceMeta });
|
||||
|
||||
expect(pushSpy).not.toHaveBeenCalled();
|
||||
await expect(models.workspaceMeta.getByParentId(workspace._id)).resolves.toStrictEqual(workspaceMeta);
|
||||
});
|
||||
|
||||
it('should push snapshot if conditions are met', async () => {
|
||||
const project = await models.project.create({ remoteId: 'abc' });
|
||||
const project = await models.project.create({ remoteId: 'abc', parentId: 'team_abc' });
|
||||
const workspace = await models.workspace.create({ parentId: project._id });
|
||||
const workspaceMeta = await models.workspaceMeta.create({ parentId: workspace._id, pushSnapshotOnInitialize: true });
|
||||
await models.workspaceMeta.create({ parentId: workspace._id, pushSnapshotOnInitialize: true });
|
||||
vcs.switchAndCreateBackendProjectIfNotExist(workspace._id, workspace.name);
|
||||
|
||||
await pushSnapshotOnInitialize({ vcs, project, workspace, workspaceMeta });
|
||||
await pushSnapshotOnInitialize({ vcs, project, workspace });
|
||||
|
||||
expect(pushSpy).toHaveBeenCalledWith(project.remoteId);
|
||||
expect(pushSpy).toHaveBeenCalledWith({ teamId: 'team_abc', teamProjectId: project.remoteId });
|
||||
const updatedMeta = await models.workspaceMeta.getByParentId(workspace._id);
|
||||
expect(updatedMeta?.pushSnapshotOnInitialize).toBe(false);
|
||||
});
|
||||
|
||||
@@ -1,54 +0,0 @@
|
||||
import { createBuilder } from '@develohpanda/fluent-builder';
|
||||
import { beforeEach, describe, expect, it } from '@jest/globals';
|
||||
|
||||
import { globalBeforeEach } from '../../../__jest__/before-each';
|
||||
import * as models from '../../../models';
|
||||
import { isRemoteProject, Project } from '../../../models/project';
|
||||
import { isCollection, Workspace, WorkspaceScopeKeys } from '../../../models/workspace';
|
||||
import { projectSchema, teamSchema } from '../../__schemas__/type-schemas';
|
||||
import { initializeProjectFromTeam, initializeWorkspaceFromBackendProject } from '../initialize-model-from';
|
||||
|
||||
const teamBuilder = createBuilder(teamSchema);
|
||||
const backendProjectBuilder = createBuilder(projectSchema);
|
||||
|
||||
describe('initializeProjectFromTeam', () => {
|
||||
beforeEach(globalBeforeEach);
|
||||
|
||||
it('should initialize project with properties from the team', async () => {
|
||||
// Arrange
|
||||
const team = teamBuilder.build();
|
||||
|
||||
// Act
|
||||
const project = await initializeProjectFromTeam(team);
|
||||
|
||||
// Assert
|
||||
expect(isRemoteProject(project)).toBe(true);
|
||||
expect(project).toMatchObject<Partial<Project>>({
|
||||
_id:`${models.project.prefix}_${team.id}`,
|
||||
remoteId: team.id,
|
||||
name: team.name,
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
describe('initializeWorkspaceFromProject', () => {
|
||||
beforeEach(globalBeforeEach);
|
||||
|
||||
it('should initialize workspac with properties from the backendProject and project', async () => {
|
||||
// Arrange
|
||||
const project = await models.project.create();
|
||||
const backendProject = backendProjectBuilder.build();
|
||||
|
||||
// Act
|
||||
const workspace = await initializeWorkspaceFromBackendProject(backendProject, project);
|
||||
|
||||
// Assert
|
||||
expect(isCollection(workspace)).toBe(true);
|
||||
expect(workspace).toMatchObject<Partial<Workspace>>({
|
||||
_id: backendProject.rootDocumentId,
|
||||
name: backendProject.name,
|
||||
parentId: project._id,
|
||||
scope: WorkspaceScopeKeys.collection,
|
||||
});
|
||||
});
|
||||
});
|
||||
@@ -4,11 +4,9 @@ import { mocked } from 'jest-mock';
|
||||
|
||||
import { globalBeforeEach } from '../../../__jest__/before-each';
|
||||
import { isLoggedIn as _isLoggedIn } from '../../../account/session';
|
||||
import { database } from '../../../common/database';
|
||||
import * as models from '../../../models';
|
||||
import { backendProjectWithTeamSchema, teamSchema } from '../../__schemas__/type-schemas';
|
||||
import MemoryDriver from '../../store/drivers/memory-driver';
|
||||
import { initializeProjectFromTeam } from '../initialize-model-from';
|
||||
import { migrateCollectionsIntoRemoteProject } from '../migrate-collections';
|
||||
import { VCS } from '../vcs';
|
||||
|
||||
@@ -78,60 +76,4 @@ describe('migrateCollectionsIntoRemoteProject', () => {
|
||||
expect(vcs.remoteBackendProjectsInAnyTeam).not.toHaveBeenCalled();
|
||||
await expect(models.workspace.getById(workspaceInLocal._id)).resolves.toStrictEqual(workspaceInLocal);
|
||||
});
|
||||
|
||||
it('does migrate if collection in non-remote project with local backend project - create remote project', async () => {
|
||||
// Arrange
|
||||
const vcs = newMockedVcs();
|
||||
const localProject = await models.project.create();
|
||||
const workspaceInLocal = await models.workspace.create({ parentId: localProject._id });
|
||||
|
||||
const team = teamBuilder.build();
|
||||
const remoteBackendProjectWithTeam = projectWithTeamBuilder
|
||||
.rootDocumentId(workspaceInLocal._id)
|
||||
.team(team)
|
||||
.build();
|
||||
|
||||
vcs.hasBackendProjectForRootDocument.mockResolvedValue(true); // has local backend project
|
||||
vcs.remoteBackendProjectsInAnyTeam.mockResolvedValue([remoteBackendProjectWithTeam]); // has local backend project
|
||||
|
||||
// Act
|
||||
await migrateCollectionsIntoRemoteProject(vcs);
|
||||
|
||||
// Assert
|
||||
expect(vcs.remoteBackendProjectsInAnyTeam).toHaveBeenCalledTimes(1);
|
||||
const createdRemoteProject = await models.project.getByRemoteId(team.id);
|
||||
await expect(models.workspace.getById(workspaceInLocal._id)).resolves.toMatchObject({
|
||||
...workspaceInLocal,
|
||||
parentId: createdRemoteProject?._id,
|
||||
});
|
||||
});
|
||||
|
||||
it('does migrate if collection in non-remote project with local backend project - use existing remote project', async () => {
|
||||
// Arrange
|
||||
const vcs = newMockedVcs();
|
||||
const localProject = await models.project.create();
|
||||
const workspaceInLocal = await models.workspace.create({ parentId: localProject._id });
|
||||
|
||||
const team = teamBuilder.build();
|
||||
const existingRemoteProject = await initializeProjectFromTeam(team);
|
||||
await database.batchModifyDocs({ upsert: [existingRemoteProject] });
|
||||
|
||||
const remoteProjectWithTeam = projectWithTeamBuilder
|
||||
.rootDocumentId(workspaceInLocal._id)
|
||||
.team(team)
|
||||
.build();
|
||||
|
||||
vcs.hasBackendProjectForRootDocument.mockResolvedValue(true); // has local backend project
|
||||
vcs.remoteBackendProjectsInAnyTeam.mockResolvedValue([remoteProjectWithTeam]); // has local backend project
|
||||
|
||||
// Act
|
||||
await migrateCollectionsIntoRemoteProject(vcs);
|
||||
|
||||
// Assert
|
||||
expect(vcs.remoteBackendProjectsInAnyTeam).toHaveBeenCalledTimes(1);
|
||||
await expect(models.workspace.getById(workspaceInLocal._id)).resolves.toMatchObject({
|
||||
...workspaceInLocal,
|
||||
parentId: existingRemoteProject?._id,
|
||||
});
|
||||
});
|
||||
});
|
||||
@@ -5,7 +5,6 @@ import { mocked } from 'jest-mock';
|
||||
import { globalBeforeEach } from '../../../__jest__/before-each';
|
||||
import { DEFAULT_BRANCH_NAME } from '../../../common/constants';
|
||||
import * as models from '../../../models';
|
||||
import { isRemoteProject } from '../../../models/project';
|
||||
import { Workspace } from '../../../models/workspace';
|
||||
import { backendProjectWithTeamSchema } from '../../__schemas__/type-schemas';
|
||||
import MemoryDriver from '../../store/drivers/memory-driver';
|
||||
@@ -49,7 +48,7 @@ describe('pullBackendProject()', () => {
|
||||
});
|
||||
|
||||
// Act
|
||||
await pullBackendProject({ vcs, backendProject, remoteProjects: [project].filter(isRemoteProject) });
|
||||
await pullBackendProject({ vcs, backendProject, remoteProject: project });
|
||||
|
||||
// Assert
|
||||
expect(project?.name).not.toBe(backendProject.team.name); // should not rename if the project already exists
|
||||
@@ -57,51 +56,60 @@ describe('pullBackendProject()', () => {
|
||||
const workspaces = await models.workspace.all();
|
||||
expect(workspaces).toHaveLength(1);
|
||||
const workspace = workspaces[0];
|
||||
expect(workspace).toStrictEqual(expect.objectContaining<Partial<Workspace>>({
|
||||
const expectedWorkspace: Partial<Workspace> = {
|
||||
_id: backendProject.rootDocumentId,
|
||||
name: backendProject.name,
|
||||
parentId: project._id,
|
||||
scope: 'collection',
|
||||
}));
|
||||
};
|
||||
|
||||
expect(workspace).toEqual(expect.objectContaining(expectedWorkspace));
|
||||
});
|
||||
|
||||
it('should insert a project and workspace with parent', async () => {
|
||||
const project = await models.project.create({
|
||||
name: `${backendProject.team.name} unique`,
|
||||
remoteId: backendProject.team.id,
|
||||
});
|
||||
// Act
|
||||
await pullBackendProject({ vcs, backendProject, remoteProjects: [] });
|
||||
await pullBackendProject({ vcs, backendProject, remoteProject: project });
|
||||
|
||||
// Assert
|
||||
const project = await models.project.getByRemoteId(backendProject.team.id);
|
||||
expect(project?.name).toBe(backendProject.team.name);
|
||||
|
||||
const workspaces = await models.workspace.all();
|
||||
expect(workspaces).toHaveLength(1);
|
||||
const workspace = workspaces[0];
|
||||
expect(workspace).toStrictEqual(expect.objectContaining<Partial<Workspace>>({
|
||||
const expectedWorkspace: Partial<Workspace> = {
|
||||
_id: backendProject.rootDocumentId,
|
||||
name: backendProject.name,
|
||||
parentId: project?._id,
|
||||
scope: 'collection',
|
||||
}));
|
||||
};
|
||||
|
||||
expect(workspace).toStrictEqual(expect.objectContaining(expectedWorkspace));
|
||||
});
|
||||
|
||||
it('should update a workspace if the name or parentId is different', async () => {
|
||||
// Arrange
|
||||
await models.workspace.create({ _id: backendProject.rootDocumentId, name: 'someName' });
|
||||
|
||||
const project = await models.project.create({
|
||||
name: `${backendProject.team.name} unique`,
|
||||
remoteId: backendProject.team.id,
|
||||
});
|
||||
// Act
|
||||
await pullBackendProject({ vcs, backendProject, remoteProjects: [] });
|
||||
await pullBackendProject({ vcs, backendProject, remoteProject: project });
|
||||
|
||||
// Assert
|
||||
const project = await models.project.getByRemoteId(backendProject.team.id);
|
||||
|
||||
const workspaces = await models.workspace.all();
|
||||
expect(workspaces).toHaveLength(1);
|
||||
const workspace = workspaces[0];
|
||||
expect(workspace).toStrictEqual(expect.objectContaining<Partial<Workspace>>({
|
||||
const expectedWorkspace: Partial<Workspace> = {
|
||||
_id: backendProject.rootDocumentId,
|
||||
name: backendProject.name,
|
||||
parentId: project?._id,
|
||||
}));
|
||||
};
|
||||
|
||||
expect(workspace).toStrictEqual(expect.objectContaining(expectedWorkspace));
|
||||
});
|
||||
});
|
||||
|
||||
@@ -113,28 +121,31 @@ describe('pullBackendProject()', () => {
|
||||
const existingReq = await models.request.create({ parentId: existingWrk._id });
|
||||
|
||||
vcs.allDocuments.mockResolvedValue([existingWrk, existingReq]);
|
||||
|
||||
const project = await models.project.create({
|
||||
name: `${backendProject.team.name} unique`,
|
||||
remoteId: backendProject.team.id,
|
||||
});
|
||||
// Act
|
||||
await pullBackendProject({ vcs, backendProject, remoteProjects: [] });
|
||||
await pullBackendProject({ vcs, backendProject, remoteProject: project });
|
||||
|
||||
// Assert
|
||||
const project = await models.project.getByRemoteId(backendProject.team.id);
|
||||
|
||||
const workspaces = await models.workspace.all();
|
||||
expect(workspaces).toHaveLength(1);
|
||||
const workspace = workspaces[0];
|
||||
expect(workspace).toStrictEqual(expect.objectContaining<Partial<Workspace>>({
|
||||
const expectedWorkspace: Partial<Workspace> = {
|
||||
_id: backendProject.rootDocumentId,
|
||||
name: backendProject.name,
|
||||
parentId: project?._id,
|
||||
}));
|
||||
};
|
||||
|
||||
expect(workspace).toStrictEqual(expect.objectContaining(expectedWorkspace));
|
||||
|
||||
const requests = await models.request.all();
|
||||
expect(requests).toHaveLength(1);
|
||||
const request = requests[0];
|
||||
expect(request).toStrictEqual(existingReq);
|
||||
|
||||
expect(vcs.pull).toHaveBeenCalledWith([], project?.remoteId);
|
||||
expect(vcs.pull).toHaveBeenCalledWith({ candidates: [], teamId: project?.parentId, teamProjectId: project?._id });
|
||||
});
|
||||
});
|
||||
|
||||
@@ -143,7 +154,7 @@ describe('pullBackendProject()', () => {
|
||||
vcs.getRemoteBranches.mockRejectedValue(new Error('invalid access to project'));
|
||||
|
||||
// Act
|
||||
const action = () => pullBackendProject({ vcs, backendProject, remoteProjects: [] });
|
||||
const action = () => pullBackendProject({ vcs, backendProject, remoteProject: { remoteId: '' } });
|
||||
|
||||
// Assert
|
||||
expect(vcs.pull).not.toHaveBeenCalled();
|
||||
|
||||
@@ -3,7 +3,6 @@ import * as models from '../../models';
|
||||
import { BaseModel, canSync } from '../../models';
|
||||
import { Project } from '../../models/project';
|
||||
import { Workspace } from '../../models/workspace';
|
||||
import { WorkspaceMeta } from '../../models/workspace-meta';
|
||||
import { StatusCandidate } from '../types';
|
||||
import { VCS } from './vcs';
|
||||
|
||||
@@ -34,16 +33,13 @@ export const initializeLocalBackendProjectAndMarkForSync = async ({ vcs, workspa
|
||||
export const pushSnapshotOnInitialize = async ({
|
||||
vcs,
|
||||
workspace,
|
||||
workspaceMeta,
|
||||
project: { _id: projectId, remoteId: projectRemoteId },
|
||||
project: { _id: projectId, remoteId: projectRemoteId, parentId },
|
||||
}: {
|
||||
vcs: VCS;
|
||||
workspace: Workspace;
|
||||
workspaceMeta?: WorkspaceMeta;
|
||||
project: Project;
|
||||
}) => {
|
||||
const projectIsForWorkspace = projectId === workspace.parentId;
|
||||
const markedForPush = workspaceMeta?.pushSnapshotOnInitialize;
|
||||
|
||||
// A race condition occurs in App.tsx when updating the active workspace
|
||||
// One code path is that a React Key updates, forcing all children to unmount and remount (https://github.com/Kong/insomnia/blob/9a943879060927d6ab1c21d3e12daba39ad05eea/packages/insomnia-app/app/ui/containers/app.tsx#L1514-L1514)
|
||||
@@ -51,8 +47,8 @@ export const pushSnapshotOnInitialize = async ({
|
||||
// This race condition causes us to hit this codepath twice while activating a workspace but the first time it has no project so we shouldn't do anything
|
||||
const hasProject = vcs.hasBackendProject();
|
||||
|
||||
if (markedForPush && projectIsForWorkspace && projectRemoteId && hasProject) {
|
||||
if (projectIsForWorkspace && projectRemoteId && hasProject) {
|
||||
await models.workspaceMeta.updateByParentId(workspace._id, { pushSnapshotOnInitialize: false });
|
||||
await vcs.push(projectRemoteId);
|
||||
await vcs.push({ teamId: parentId, teamProjectId: projectRemoteId });
|
||||
}
|
||||
};
|
||||
@@ -1,25 +0,0 @@
|
||||
import * as models from '../../models';
|
||||
import { RemoteProject } from '../../models/project';
|
||||
import { Project } from '../../models/project';
|
||||
import { Workspace, WorkspaceScopeKeys } from '../../models/workspace';
|
||||
import { Team } from '../types';
|
||||
import { BackendProject } from '../types';
|
||||
|
||||
export const initializeProjectFromTeam = (team: Team) => models.initModel<RemoteProject>(
|
||||
models.project.type,
|
||||
{
|
||||
_id: `${models.project.prefix}_${team.id}`,
|
||||
remoteId: team.id,
|
||||
name: team.name,
|
||||
}
|
||||
);
|
||||
|
||||
export const initializeWorkspaceFromBackendProject = (backendProject: BackendProject, project: Project) => models.initModel<Workspace>(
|
||||
models.workspace.type,
|
||||
{
|
||||
_id: backendProject.rootDocumentId,
|
||||
name: backendProject.name,
|
||||
parentId: project._id,
|
||||
scope: WorkspaceScopeKeys.collection,
|
||||
}
|
||||
);
|
||||
Loaded 100 of 204 files, more files were not shown because too many files have changed in this diff.
Show more
Reference in new issue
Block a user