{
  "info": {
    "_postman_id": "d84b8778-d062-4295-9543-0401eac2c654",
    "name": "demo API",
    "description": "Item CRUD + auth. Generated from /v3/api-docs (see docs/postman/README.md) and enriched. Uses environment variables only.",
    "schema": "https://schema.getpostman.com/json/collection/v2.1.0/collection.json"
  },
  "auth": {
    "type": "bearer",
    "bearer": [
      {
        "key": "token",
        "value": "{{accessToken}}",
        "type": "string"
      }
    ]
  },
  "item": [
    {
      "name": "Auth",
      "item": [
        {
          "name": "Register",
          "request": {
            "method": "POST",
            "header": [
              {
                "key": "Content-Type",
                "value": "application/json"
              }
            ],
            "url": {
              "raw": "{{baseUrl}}/api/v1/auth/register",
              "host": [
                "{{baseUrl}}"
              ],
              "path": [
                "api",
                "v1",
                "auth",
                "register"
              ]
            },
            "body": {
              "mode": "raw",
              "raw": "{\"email\":\"{{email}}\",\"password\":\"{{password}}\"}"
            },
            "auth": {
              "type": "noauth"
            }
          },
          "response": [],
          "event": [
            {
              "listen": "test",
              "script": {
                "type": "text/javascript",
                "exec": [
                  "pm.test(\"register 201\", () => pm.response.to.have.status(201));",
                  "pm.test(\"ack message\", () => pm.expect(pm.response.json()).to.have.property(\"message\"));"
                ]
              }
            }
          ]
        },
        {
          "name": "Activate",
          "request": {
            "method": "POST",
            "header": [
              {
                "key": "Content-Type",
                "value": "application/json"
              }
            ],
            "url": {
              "raw": "{{baseUrl}}/api/v1/auth/activate",
              "host": [
                "{{baseUrl}}"
              ],
              "path": [
                "api",
                "v1",
                "auth",
                "activate"
              ]
            },
            "body": {
              "mode": "raw",
              "raw": "{\"token\":\"{{activationToken}}\"}"
            },
            "auth": {
              "type": "noauth"
            }
          },
          "response": [],
          "event": [
            {
              "listen": "prerequest",
              "script": {
                "type": "text/javascript",
                "exec": [
                  "const url = pm.environment.get(\"mailhogUrl\") + \"/api/v2/messages?limit=100\";",
                  "const email = (pm.environment.get(\"email\") || \"\").toLowerCase();",
                  "const re = new RegExp(\"activation token is: (\\\\S+)\");",
                  "pm.sendRequest(url, (err, res) => {",
                  "  if (err) { console.log(\"mailhog\", err); return; }",
                  "  const items = (res.json().items) || [];",
                  "  for (const it of items) {",
                  "    const to = (it.To || []).map(t => (t.Mailbox + \"@\" + t.Domain).toLowerCase());",
                  "    if (to.indexOf(email) === -1) continue;",
                  "    const body = (it.Content && it.Content.Body) ? it.Content.Body : \"\";",
                  "    const m = body.match(re);",
                  "    if (m) { pm.environment.set(\"activationToken\", m[1]); break; }",
                  "  }",
                  "});"
                ]
              }
            },
            {
              "listen": "test",
              "script": {
                "type": "text/javascript",
                "exec": [
                  "pm.test(\"activate 200\", () => pm.response.to.have.status(200));"
                ]
              }
            }
          ]
        },
        {
          "name": "Resend Activation",
          "request": {
            "method": "POST",
            "header": [
              {
                "key": "Content-Type",
                "value": "application/json"
              }
            ],
            "url": {
              "raw": "{{baseUrl}}/api/v1/auth/activation/resend",
              "host": [
                "{{baseUrl}}"
              ],
              "path": [
                "api",
                "v1",
                "auth",
                "activation",
                "resend"
              ]
            },
            "body": {
              "mode": "raw",
              "raw": "{\"email\":\"{{email}}\"}"
            },
            "auth": {
              "type": "noauth"
            }
          },
          "response": [],
          "event": [
            {
              "listen": "test",
              "script": {
                "type": "text/javascript",
                "exec": [
                  "pm.test(\"resend 202\", () => pm.response.to.have.status(202));"
                ]
              }
            }
          ]
        },
        {
          "name": "Login",
          "request": {
            "method": "POST",
            "header": [
              {
                "key": "Content-Type",
                "value": "application/json"
              }
            ],
            "url": {
              "raw": "{{baseUrl}}/api/v1/auth/login",
              "host": [
                "{{baseUrl}}"
              ],
              "path": [
                "api",
                "v1",
                "auth",
                "login"
              ]
            },
            "body": {
              "mode": "raw",
              "raw": "{\"email\":\"{{email}}\",\"password\":\"{{password}}\"}"
            },
            "auth": {
              "type": "noauth"
            }
          },
          "response": [],
          "event": [
            {
              "listen": "test",
              "script": {
                "type": "text/javascript",
                "exec": [
                  "const b = pm.response.json();",
                  "pm.test(\"login 200\", () => pm.response.to.have.status(200));",
                  "pm.test(\"has tokens\", () => { pm.expect(b).to.have.property(\"accessToken\"); pm.expect(b).to.have.property(\"refreshToken\"); pm.expect(b.expiresIn).to.be.a(\"number\"); });",
                  "pm.environment.set(\"accessToken\", b.accessToken);",
                  "pm.environment.set(\"refreshToken\", b.refreshToken);"
                ]
              }
            }
          ]
        },
        {
          "name": "Refresh",
          "request": {
            "method": "POST",
            "header": [
              {
                "key": "Content-Type",
                "value": "application/json"
              }
            ],
            "url": {
              "raw": "{{baseUrl}}/api/v1/auth/refresh",
              "host": [
                "{{baseUrl}}"
              ],
              "path": [
                "api",
                "v1",
                "auth",
                "refresh"
              ]
            },
            "body": {
              "mode": "raw",
              "raw": "{\"refreshToken\":\"{{refreshToken}}\"}"
            },
            "auth": {
              "type": "noauth"
            }
          },
          "response": [],
          "event": [
            {
              "listen": "test",
              "script": {
                "type": "text/javascript",
                "exec": [
                  "const b = pm.response.json();",
                  "pm.test(\"refresh 200\", () => pm.response.to.have.status(200));",
                  "pm.environment.set(\"accessToken\", b.accessToken);",
                  "pm.environment.set(\"refreshToken\", b.refreshToken);"
                ]
              }
            }
          ]
        },
        {
          "name": "Logout",
          "request": {
            "method": "POST",
            "header": [
              {
                "key": "Content-Type",
                "value": "application/json"
              }
            ],
            "url": {
              "raw": "{{baseUrl}}/api/v1/auth/logout",
              "host": [
                "{{baseUrl}}"
              ],
              "path": [
                "api",
                "v1",
                "auth",
                "logout"
              ]
            },
            "body": {
              "mode": "raw",
              "raw": "{\"refreshToken\":\"{{refreshToken}}\"}"
            },
            "auth": {
              "type": "noauth"
            }
          },
          "response": [],
          "event": [
            {
              "listen": "test",
              "script": {
                "type": "text/javascript",
                "exec": [
                  "pm.test(\"logout 204\", () => pm.response.to.have.status(204));"
                ]
              }
            }
          ]
        },
        {
          "name": "Forgot Password",
          "request": {
            "method": "POST",
            "header": [
              {
                "key": "Content-Type",
                "value": "application/json"
              }
            ],
            "url": {
              "raw": "{{baseUrl}}/api/v1/auth/password/forgot",
              "host": [
                "{{baseUrl}}"
              ],
              "path": [
                "api",
                "v1",
                "auth",
                "password",
                "forgot"
              ]
            },
            "body": {
              "mode": "raw",
              "raw": "{\"email\":\"{{email}}\"}"
            },
            "auth": {
              "type": "noauth"
            }
          },
          "response": [],
          "event": [
            {
              "listen": "test",
              "script": {
                "type": "text/javascript",
                "exec": [
                  "pm.test(\"forgot 202\", () => pm.response.to.have.status(202));"
                ]
              }
            }
          ]
        },
        {
          "name": "Reset Password",
          "request": {
            "method": "POST",
            "header": [
              {
                "key": "Content-Type",
                "value": "application/json"
              }
            ],
            "url": {
              "raw": "{{baseUrl}}/api/v1/auth/password/reset",
              "host": [
                "{{baseUrl}}"
              ],
              "path": [
                "api",
                "v1",
                "auth",
                "password",
                "reset"
              ]
            },
            "body": {
              "mode": "raw",
              "raw": "{\"token\":\"{{resetToken}}\",\"newPassword\":\"{{newPassword}}\"}"
            },
            "auth": {
              "type": "noauth"
            }
          },
          "response": [],
          "event": [
            {
              "listen": "prerequest",
              "script": {
                "type": "text/javascript",
                "exec": [
                  "const url = pm.environment.get(\"mailhogUrl\") + \"/api/v2/messages?limit=100\";",
                  "const email = (pm.environment.get(\"email\") || \"\").toLowerCase();",
                  "const re = new RegExp(\"reset token is: (\\\\S+)\");",
                  "pm.sendRequest(url, (err, res) => {",
                  "  if (err) { console.log(\"mailhog\", err); return; }",
                  "  const items = (res.json().items) || [];",
                  "  for (const it of items) {",
                  "    const to = (it.To || []).map(t => (t.Mailbox + \"@\" + t.Domain).toLowerCase());",
                  "    if (to.indexOf(email) === -1) continue;",
                  "    const body = (it.Content && it.Content.Body) ? it.Content.Body : \"\";",
                  "    const m = body.match(re);",
                  "    if (m) { pm.environment.set(\"resetToken\", m[1]); break; }",
                  "  }",
                  "});"
                ]
              }
            },
            {
              "listen": "test",
              "script": {
                "type": "text/javascript",
                "exec": [
                  "pm.test(\"reset 204\", () => pm.response.to.have.status(204));"
                ]
              }
            }
          ]
        }
      ]
    },
    {
      "name": "Users",
      "item": [
        {
          "name": "Get Me",
          "request": {
            "method": "GET",
            "header": [],
            "url": {
              "raw": "{{baseUrl}}/api/v1/users/me",
              "host": [
                "{{baseUrl}}"
              ],
              "path": [
                "api",
                "v1",
                "users",
                "me"
              ]
            }
          },
          "response": [],
          "event": [
            {
              "listen": "test",
              "script": {
                "type": "text/javascript",
                "exec": [
                  "pm.test(\"me 200\", () => pm.response.to.have.status(200));",
                  "const b = pm.response.json();",
                  "pm.test(\"has email, no password\", () => { pm.expect(b).to.have.property(\"email\"); pm.expect(b).to.not.have.property(\"password\"); });"
                ]
              }
            }
          ]
        }
      ]
    },
    {
      "name": "Items",
      "item": [
        {
          "name": "Create Item",
          "request": {
            "method": "POST",
            "header": [
              {
                "key": "Content-Type",
                "value": "application/json"
              }
            ],
            "url": {
              "raw": "{{baseUrl}}/api/v1/items",
              "host": [
                "{{baseUrl}}"
              ],
              "path": [
                "api",
                "v1",
                "items"
              ]
            },
            "body": {
              "mode": "raw",
              "raw": "{\"name\":\"{{itemName}}\",\"description\":\"a widget\"}"
            }
          },
          "response": [],
          "event": [
            {
              "listen": "test",
              "script": {
                "type": "text/javascript",
                "exec": [
                  "pm.test(\"create 201\", () => pm.response.to.have.status(201));",
                  "pm.test(\"has Location\", () => pm.expect(pm.response.headers.get(\"Location\")).to.include(\"/api/v1/items/\"));",
                  "pm.environment.set(\"itemId\", pm.response.json().id);"
                ]
              }
            }
          ]
        },
        {
          "name": "List Items",
          "request": {
            "method": "GET",
            "header": [],
            "url": {
              "raw": "{{baseUrl}}/api/v1/items?page=0&size=20",
              "host": [
                "{{baseUrl}}"
              ],
              "path": [
                "api",
                "v1",
                "items"
              ],
              "query": [
                {
                  "key": "page",
                  "value": "0"
                },
                {
                  "key": "size",
                  "value": "20"
                }
              ]
            }
          },
          "response": [],
          "event": [
            {
              "listen": "test",
              "script": {
                "type": "text/javascript",
                "exec": [
                  "pm.test(\"list 200\", () => pm.response.to.have.status(200));",
                  "pm.test(\"wrapped page\", () => pm.expect(pm.response.json()).to.have.property(\"content\"));"
                ]
              }
            }
          ]
        },
        {
          "name": "Get Item",
          "request": {
            "method": "GET",
            "header": [],
            "url": {
              "raw": "{{baseUrl}}/api/v1/items/{{itemId}}",
              "host": [
                "{{baseUrl}}"
              ],
              "path": [
                "api",
                "v1",
                "items",
                "{{itemId}}"
              ]
            }
          },
          "response": [],
          "event": [
            {
              "listen": "test",
              "script": {
                "type": "text/javascript",
                "exec": [
                  "pm.test(\"get 200\", () => pm.response.to.have.status(200));"
                ]
              }
            }
          ]
        },
        {
          "name": "Update Item",
          "request": {
            "method": "PUT",
            "header": [
              {
                "key": "Content-Type",
                "value": "application/json"
              }
            ],
            "url": {
              "raw": "{{baseUrl}}/api/v1/items/{{itemId}}",
              "host": [
                "{{baseUrl}}"
              ],
              "path": [
                "api",
                "v1",
                "items",
                "{{itemId}}"
              ]
            },
            "body": {
              "mode": "raw",
              "raw": "{\"name\":\"{{itemName}} v2\",\"description\":\"updated\",\"version\":0}"
            }
          },
          "response": [],
          "event": [
            {
              "listen": "test",
              "script": {
                "type": "text/javascript",
                "exec": [
                  "pm.test(\"put 200\", () => pm.response.to.have.status(200));",
                  "pm.test(\"version bumped\", () => pm.expect(pm.response.json().version).to.eql(1));"
                ]
              }
            }
          ]
        },
        {
          "name": "Patch Item",
          "request": {
            "method": "PATCH",
            "header": [
              {
                "key": "Content-Type",
                "value": "application/json"
              }
            ],
            "url": {
              "raw": "{{baseUrl}}/api/v1/items/{{itemId}}",
              "host": [
                "{{baseUrl}}"
              ],
              "path": [
                "api",
                "v1",
                "items",
                "{{itemId}}"
              ]
            },
            "body": {
              "mode": "raw",
              "raw": "{\"description\":null}"
            }
          },
          "response": [],
          "event": [
            {
              "listen": "test",
              "script": {
                "type": "text/javascript",
                "exec": [
                  "pm.test(\"patch 200\", () => pm.response.to.have.status(200));"
                ]
              }
            }
          ]
        },
        {
          "name": "Delete Item",
          "request": {
            "method": "DELETE",
            "header": [],
            "url": {
              "raw": "{{baseUrl}}/api/v1/items/{{itemId}}",
              "host": [
                "{{baseUrl}}"
              ],
              "path": [
                "api",
                "v1",
                "items",
                "{{itemId}}"
              ]
            }
          },
          "response": [],
          "event": [
            {
              "listen": "test",
              "script": {
                "type": "text/javascript",
                "exec": [
                  "pm.test(\"delete 204\", () => pm.response.to.have.status(204));"
                ]
              }
            }
          ]
        },
        {
          "name": "Get Missing Item (404)",
          "request": {
            "method": "GET",
            "header": [],
            "url": {
              "raw": "{{baseUrl}}/api/v1/items/00000000-0000-0000-0000-000000000000",
              "host": [
                "{{baseUrl}}"
              ],
              "path": [
                "api",
                "v1",
                "items",
                "00000000-0000-0000-0000-000000000000"
              ]
            }
          },
          "response": [],
          "event": [
            {
              "listen": "test",
              "script": {
                "type": "text/javascript",
                "exec": [
                  "pm.test(\"missing 404\", () => pm.response.to.have.status(404));",
                  "pm.test(\"code ITEM_NOT_FOUND\", () => pm.expect(pm.response.json().code).to.eql(\"ITEM_NOT_FOUND\"));"
                ]
              }
            }
          ]
        }
      ]
    },
    {
      "name": "Negative paths",
      "item": [
        {
          "name": "Login wrong password (401)",
          "request": {
            "method": "POST",
            "header": [
              {
                "key": "Content-Type",
                "value": "application/json"
              }
            ],
            "url": {
              "raw": "{{baseUrl}}/api/v1/auth/login",
              "host": [
                "{{baseUrl}}"
              ],
              "path": [
                "api",
                "v1",
                "auth",
                "login"
              ]
            },
            "body": {
              "mode": "raw",
              "raw": "{\"email\":\"{{email}}\",\"password\":\"totally-wrong-pass\"}"
            },
            "auth": {
              "type": "noauth"
            }
          },
          "response": [],
          "event": [
            {
              "listen": "test",
              "script": {
                "type": "text/javascript",
                "exec": [
                  "pm.test(\"401\", () => pm.response.to.have.status(401));",
                  "pm.test(\"code INVALID_CREDENTIALS\", () => pm.expect(pm.response.json().code).to.eql(\"INVALID_CREDENTIALS\"));"
                ]
              }
            }
          ]
        },
        {
          "name": "Protected without token (401)",
          "request": {
            "method": "GET",
            "header": [],
            "url": {
              "raw": "{{baseUrl}}/api/v1/items",
              "host": [
                "{{baseUrl}}"
              ],
              "path": [
                "api",
                "v1",
                "items"
              ]
            },
            "auth": {
              "type": "noauth"
            }
          },
          "response": [],
          "event": [
            {
              "listen": "test",
              "script": {
                "type": "text/javascript",
                "exec": [
                  "pm.test(\"401\", () => pm.response.to.have.status(401));"
                ]
              }
            }
          ]
        },
        {
          "name": "Tampered token (401)",
          "request": {
            "method": "GET",
            "header": [],
            "url": {
              "raw": "{{baseUrl}}/api/v1/users/me",
              "host": [
                "{{baseUrl}}"
              ],
              "path": [
                "api",
                "v1",
                "users",
                "me"
              ]
            }
          },
          "response": [],
          "event": [
            {
              "listen": "prerequest",
              "script": {
                "type": "text/javascript",
                "exec": [
                  "pm.request.headers.upsert({key:\"Authorization\", value:\"Bearer not.a.jwt\"});"
                ]
              }
            },
            {
              "listen": "test",
              "script": {
                "type": "text/javascript",
                "exec": [
                  "pm.test(\"401\", () => pm.response.to.have.status(401));"
                ]
              }
            }
          ]
        },
        {
          "name": "Reset with bogus token (400)",
          "request": {
            "method": "POST",
            "header": [
              {
                "key": "Content-Type",
                "value": "application/json"
              }
            ],
            "url": {
              "raw": "{{baseUrl}}/api/v1/auth/password/reset",
              "host": [
                "{{baseUrl}}"
              ],
              "path": [
                "api",
                "v1",
                "auth",
                "password",
                "reset"
              ]
            },
            "body": {
              "mode": "raw",
              "raw": "{\"token\":\"definitely-not-valid\",\"newPassword\":\"a valid passphrase\"}"
            },
            "auth": {
              "type": "noauth"
            }
          },
          "response": [],
          "event": [
            {
              "listen": "test",
              "script": {
                "type": "text/javascript",
                "exec": [
                  "pm.test(\"400\", () => pm.response.to.have.status(400));",
                  "pm.test(\"code TOKEN_INVALID\", () => pm.expect(pm.response.json().code).to.eql(\"TOKEN_INVALID\"));"
                ]
              }
            }
          ]
        }
      ]
    },
    {
      "name": "Smoke",
      "item": [
        {
          "name": "Register",
          "request": {
            "method": "POST",
            "header": [
              {
                "key": "Content-Type",
                "value": "application/json"
              }
            ],
            "url": {
              "raw": "{{baseUrl}}/api/v1/auth/register",
              "host": [
                "{{baseUrl}}"
              ],
              "path": [
                "api",
                "v1",
                "auth",
                "register"
              ]
            },
            "body": {
              "mode": "raw",
              "raw": "{\"email\":\"{{smokeEmail}}\",\"password\":\"{{password}}\"}"
            },
            "auth": {
              "type": "noauth"
            }
          },
          "response": [],
          "event": [
            {
              "listen": "prerequest",
              "script": {
                "type": "text/javascript",
                "exec": [
                  "pm.environment.set(\"smokeEmail\", \"smoke+\" + Date.now() + \"@example.com\");"
                ]
              }
            },
            {
              "listen": "test",
              "script": {
                "type": "text/javascript",
                "exec": [
                  "pm.test(\"register 201\", () => pm.response.to.have.status(201));"
                ]
              }
            }
          ]
        },
        {
          "name": "Activate",
          "request": {
            "method": "POST",
            "header": [
              {
                "key": "Content-Type",
                "value": "application/json"
              }
            ],
            "url": {
              "raw": "{{baseUrl}}/api/v1/auth/activate",
              "host": [
                "{{baseUrl}}"
              ],
              "path": [
                "api",
                "v1",
                "auth",
                "activate"
              ]
            },
            "body": {
              "mode": "raw",
              "raw": "{\"token\":\"{{activationToken}}\"}"
            },
            "auth": {
              "type": "noauth"
            }
          },
          "response": [],
          "event": [
            {
              "listen": "prerequest",
              "script": {
                "type": "text/javascript",
                "exec": [
                  "const url = pm.environment.get(\"mailhogUrl\") + \"/api/v2/messages?limit=100\";",
                  "const email = (pm.environment.get(\"smokeEmail\") || \"\").toLowerCase();",
                  "const re = new RegExp(\"activation token is: (\\\\S+)\");",
                  "pm.sendRequest(url, (err, res) => {",
                  "  if (err) { console.log(\"mailhog\", err); return; }",
                  "  const items = (res.json().items) || [];",
                  "  for (const it of items) {",
                  "    const to = (it.To || []).map(t => (t.Mailbox + \"@\" + t.Domain).toLowerCase());",
                  "    if (to.indexOf(email) === -1) continue;",
                  "    const body = (it.Content && it.Content.Body) ? it.Content.Body : \"\";",
                  "    const m = body.match(re);",
                  "    if (m) { pm.environment.set(\"activationToken\", m[1]); break; }",
                  "  }",
                  "});"
                ]
              }
            },
            {
              "listen": "test",
              "script": {
                "type": "text/javascript",
                "exec": [
                  "pm.test(\"activate 200\", () => pm.response.to.have.status(200));"
                ]
              }
            }
          ]
        },
        {
          "name": "Login",
          "request": {
            "method": "POST",
            "header": [
              {
                "key": "Content-Type",
                "value": "application/json"
              }
            ],
            "url": {
              "raw": "{{baseUrl}}/api/v1/auth/login",
              "host": [
                "{{baseUrl}}"
              ],
              "path": [
                "api",
                "v1",
                "auth",
                "login"
              ]
            },
            "body": {
              "mode": "raw",
              "raw": "{\"email\":\"{{smokeEmail}}\",\"password\":\"{{password}}\"}"
            },
            "auth": {
              "type": "noauth"
            }
          },
          "response": [],
          "event": [
            {
              "listen": "test",
              "script": {
                "type": "text/javascript",
                "exec": [
                  "const b = pm.response.json();",
                  "pm.test(\"login 200\", () => pm.response.to.have.status(200));",
                  "pm.test(\"has tokens\", () => { pm.expect(b).to.have.property(\"accessToken\"); pm.expect(b).to.have.property(\"refreshToken\"); pm.expect(b.expiresIn).to.be.a(\"number\"); });",
                  "pm.environment.set(\"accessToken\", b.accessToken);",
                  "pm.environment.set(\"refreshToken\", b.refreshToken);"
                ]
              }
            }
          ]
        },
        {
          "name": "Create Item",
          "request": {
            "method": "POST",
            "header": [
              {
                "key": "Content-Type",
                "value": "application/json"
              }
            ],
            "url": {
              "raw": "{{baseUrl}}/api/v1/items",
              "host": [
                "{{baseUrl}}"
              ],
              "path": [
                "api",
                "v1",
                "items"
              ]
            },
            "body": {
              "mode": "raw",
              "raw": "{\"name\":\"Smoke {{smokeEmail}}\",\"description\":\"e2e\"}"
            }
          },
          "response": [],
          "event": [
            {
              "listen": "test",
              "script": {
                "type": "text/javascript",
                "exec": [
                  "pm.test(\"create 201\", () => pm.response.to.have.status(201));",
                  "pm.test(\"has Location\", () => pm.expect(pm.response.headers.get(\"Location\")).to.include(\"/api/v1/items/\"));",
                  "pm.environment.set(\"itemId\", pm.response.json().id);"
                ]
              }
            }
          ]
        },
        {
          "name": "List Items",
          "request": {
            "method": "GET",
            "header": [],
            "url": {
              "raw": "{{baseUrl}}/api/v1/items?size=5",
              "host": [
                "{{baseUrl}}"
              ],
              "path": [
                "api",
                "v1",
                "items"
              ],
              "query": [
                {
                  "key": "size",
                  "value": "5"
                }
              ]
            }
          },
          "response": [],
          "event": [
            {
              "listen": "test",
              "script": {
                "type": "text/javascript",
                "exec": [
                  "pm.test(\"list 200\", () => pm.response.to.have.status(200));"
                ]
              }
            }
          ]
        },
        {
          "name": "Get Item",
          "request": {
            "method": "GET",
            "header": [],
            "url": {
              "raw": "{{baseUrl}}/api/v1/items/{{itemId}}",
              "host": [
                "{{baseUrl}}"
              ],
              "path": [
                "api",
                "v1",
                "items",
                "{{itemId}}"
              ]
            }
          },
          "response": [],
          "event": [
            {
              "listen": "test",
              "script": {
                "type": "text/javascript",
                "exec": [
                  "pm.test(\"get 200\", () => pm.response.to.have.status(200));"
                ]
              }
            }
          ]
        },
        {
          "name": "Update Item",
          "request": {
            "method": "PUT",
            "header": [
              {
                "key": "Content-Type",
                "value": "application/json"
              }
            ],
            "url": {
              "raw": "{{baseUrl}}/api/v1/items/{{itemId}}",
              "host": [
                "{{baseUrl}}"
              ],
              "path": [
                "api",
                "v1",
                "items",
                "{{itemId}}"
              ]
            },
            "body": {
              "mode": "raw",
              "raw": "{\"name\":\"Smoke updated\",\"description\":\"u\",\"version\":0}"
            }
          },
          "response": [],
          "event": [
            {
              "listen": "test",
              "script": {
                "type": "text/javascript",
                "exec": [
                  "pm.test(\"put 200\", () => pm.response.to.have.status(200));"
                ]
              }
            }
          ]
        },
        {
          "name": "Delete Item",
          "request": {
            "method": "DELETE",
            "header": [],
            "url": {
              "raw": "{{baseUrl}}/api/v1/items/{{itemId}}",
              "host": [
                "{{baseUrl}}"
              ],
              "path": [
                "api",
                "v1",
                "items",
                "{{itemId}}"
              ]
            }
          },
          "response": [],
          "event": [
            {
              "listen": "test",
              "script": {
                "type": "text/javascript",
                "exec": [
                  "pm.test(\"delete 204\", () => pm.response.to.have.status(204));"
                ]
              }
            }
          ]
        },
        {
          "name": "Refresh",
          "request": {
            "method": "POST",
            "header": [
              {
                "key": "Content-Type",
                "value": "application/json"
              }
            ],
            "url": {
              "raw": "{{baseUrl}}/api/v1/auth/refresh",
              "host": [
                "{{baseUrl}}"
              ],
              "path": [
                "api",
                "v1",
                "auth",
                "refresh"
              ]
            },
            "body": {
              "mode": "raw",
              "raw": "{\"refreshToken\":\"{{refreshToken}}\"}"
            },
            "auth": {
              "type": "noauth"
            }
          },
          "response": [],
          "event": [
            {
              "listen": "prerequest",
              "script": {
                "type": "text/javascript",
                "exec": [
                  "pm.environment.set(\"oldRefresh\", pm.environment.get(\"refreshToken\"));"
                ]
              }
            },
            {
              "listen": "test",
              "script": {
                "type": "text/javascript",
                "exec": [
                  "const b = pm.response.json();",
                  "pm.test(\"refresh 200\", () => pm.response.to.have.status(200));",
                  "pm.environment.set(\"accessToken\", b.accessToken);",
                  "pm.environment.set(\"refreshToken\", b.refreshToken);"
                ]
              }
            }
          ]
        },
        {
          "name": "Reuse old refresh (401)",
          "request": {
            "method": "POST",
            "header": [
              {
                "key": "Content-Type",
                "value": "application/json"
              }
            ],
            "url": {
              "raw": "{{baseUrl}}/api/v1/auth/refresh",
              "host": [
                "{{baseUrl}}"
              ],
              "path": [
                "api",
                "v1",
                "auth",
                "refresh"
              ]
            },
            "body": {
              "mode": "raw",
              "raw": "{\"refreshToken\":\"{{oldRefresh}}\"}"
            },
            "auth": {
              "type": "noauth"
            }
          },
          "response": [],
          "event": [
            {
              "listen": "prerequest",
              "script": {
                "type": "text/javascript",
                "exec": [
                  "// capture the pre-refresh token before it rotates"
                ]
              }
            },
            {
              "listen": "test",
              "script": {
                "type": "text/javascript",
                "exec": [
                  "pm.test(\"reuse 401\", () => pm.response.to.have.status(401));",
                  "pm.test(\"code TOKEN_REUSE_DETECTED\", () => pm.expect(pm.response.json().code).to.eql(\"TOKEN_REUSE_DETECTED\"));"
                ]
              }
            }
          ]
        },
        {
          "name": "Logout",
          "request": {
            "method": "POST",
            "header": [
              {
                "key": "Content-Type",
                "value": "application/json"
              }
            ],
            "url": {
              "raw": "{{baseUrl}}/api/v1/auth/logout",
              "host": [
                "{{baseUrl}}"
              ],
              "path": [
                "api",
                "v1",
                "auth",
                "logout"
              ]
            },
            "body": {
              "mode": "raw",
              "raw": "{\"refreshToken\":\"{{refreshToken}}\"}"
            },
            "auth": {
              "type": "noauth"
            }
          },
          "response": [],
          "event": [
            {
              "listen": "test",
              "script": {
                "type": "text/javascript",
                "exec": [
                  "pm.test(\"logout 204\", () => pm.response.to.have.status(204));"
                ]
              }
            }
          ]
        }
      ]
    }
  ],
  "variable": [
    {
      "key": "itemName",
      "value": "Widget"
    }
  ]
}