{
  "info": {
    "name": "qa.codes — API Testing Playground",
    "description": "Practice collection for the qa.codes API Testing Playground. Covers authentication, users, products and orders with positive and negative assertions.\n\nSetup: set the `baseUrl` collection variable to your API sandbox base URL. `accessToken` is populated automatically by the Auth > Login request.\n\nThese requests are written against the documented playground endpoints; some responses intentionally contain seeded bugs — compare the assertions below against actual behaviour and report the mismatches.",
    "schema": "https://schema.getpostman.com/json/collection/v2.1.0/collection.json"
  },
  "variable": [
    {
      "key": "baseUrl",
      "value": "https://qa.codes/api/playground",
      "type": "string"
    },
    {
      "key": "accessToken",
      "value": "",
      "type": "string"
    },
    {
      "key": "userId",
      "value": "1",
      "type": "string"
    },
    {
      "key": "productId",
      "value": "1",
      "type": "string"
    }
  ],
  "item": [
    {
      "name": "Auth",
      "item": [
        {
          "name": "Login (valid)",
          "event": [
            {
              "listen": "test",
              "script": {
                "type": "text/javascript",
                "exec": [
                  "pm.test('Status is 200', () => pm.response.to.have.status(200));",
                  "const body = pm.response.json();",
                  "pm.test('Returns a token', () => pm.expect(body).to.have.property('token'));",
                  "if (body.token) pm.collectionVariables.set('accessToken', body.token);"
                ]
              }
            }
          ],
          "request": {
            "method": "POST",
            "header": [{ "key": "Content-Type", "value": "application/json" }],
            "body": {
              "mode": "raw",
              "raw": "{\n  \"email\": \"demo@qa.codes\",\n  \"password\": \"Password123!\"\n}"
            },
            "url": { "raw": "{{baseUrl}}/auth/login", "host": ["{{baseUrl}}"], "path": ["auth", "login"] }
          }
        },
        {
          "name": "Login (invalid)",
          "event": [
            {
              "listen": "test",
              "script": {
                "type": "text/javascript",
                "exec": [
                  "pm.test('Invalid login returns 401', () => pm.response.to.have.status(401));"
                ]
              }
            }
          ],
          "request": {
            "method": "POST",
            "header": [{ "key": "Content-Type", "value": "application/json" }],
            "body": {
              "mode": "raw",
              "raw": "{\n  \"email\": \"demo@qa.codes\",\n  \"password\": \"wrong\"\n}"
            },
            "url": { "raw": "{{baseUrl}}/auth/login", "host": ["{{baseUrl}}"], "path": ["auth", "login"] }
          }
        },
        {
          "name": "Refresh token",
          "request": {
            "method": "POST",
            "header": [{ "key": "Content-Type", "value": "application/json" }],
            "body": { "mode": "raw", "raw": "{\n  \"refreshToken\": \"<refresh-token>\"\n}" },
            "url": { "raw": "{{baseUrl}}/auth/refresh-token", "host": ["{{baseUrl}}"], "path": ["auth", "refresh-token"] }
          }
        }
      ]
    },
    {
      "name": "Users",
      "item": [
        {
          "name": "List users",
          "event": [
            {
              "listen": "test",
              "script": {
                "type": "text/javascript",
                "exec": [
                  "pm.test('Status is 200', () => pm.response.to.have.status(200));",
                  "pm.test('Response is an array', () => pm.expect(pm.response.json()).to.be.an('array'));"
                ]
              }
            }
          ],
          "request": {
            "method": "GET",
            "header": [{ "key": "Authorization", "value": "Bearer {{accessToken}}" }],
            "url": { "raw": "{{baseUrl}}/users", "host": ["{{baseUrl}}"], "path": ["users"] }
          }
        },
        {
          "name": "Get user by id",
          "request": {
            "method": "GET",
            "header": [{ "key": "Authorization", "value": "Bearer {{accessToken}}" }],
            "url": { "raw": "{{baseUrl}}/users/{{userId}}", "host": ["{{baseUrl}}"], "path": ["users", "{{userId}}"] }
          }
        },
        {
          "name": "Create user (missing email — expect 400)",
          "event": [
            {
              "listen": "test",
              "script": {
                "type": "text/javascript",
                "exec": [
                  "pm.test('Missing required field returns 400', () => pm.response.to.have.status(400));"
                ]
              }
            }
          ],
          "request": {
            "method": "POST",
            "header": [
              { "key": "Content-Type", "value": "application/json" },
              { "key": "Authorization", "value": "Bearer {{accessToken}}" }
            ],
            "body": { "mode": "raw", "raw": "{\n  \"name\": \"No Email User\"\n}" },
            "url": { "raw": "{{baseUrl}}/users", "host": ["{{baseUrl}}"], "path": ["users"] }
          }
        }
      ]
    },
    {
      "name": "Products",
      "item": [
        {
          "name": "List products",
          "event": [
            {
              "listen": "test",
              "script": {
                "type": "text/javascript",
                "exec": [
                  "pm.test('Status is 200', () => pm.response.to.have.status(200));"
                ]
              }
            }
          ],
          "request": {
            "method": "GET",
            "url": { "raw": "{{baseUrl}}/products", "host": ["{{baseUrl}}"], "path": ["products"] }
          }
        },
        {
          "name": "Filter by category",
          "request": {
            "method": "GET",
            "url": {
              "raw": "{{baseUrl}}/products?category=mobile",
              "host": ["{{baseUrl}}"],
              "path": ["products"],
              "query": [{ "key": "category", "value": "mobile" }]
            }
          }
        },
        {
          "name": "Paginate",
          "request": {
            "method": "GET",
            "url": {
              "raw": "{{baseUrl}}/products?page=1&limit=10",
              "host": ["{{baseUrl}}"],
              "path": ["products"],
              "query": [
                { "key": "page", "value": "1" },
                { "key": "limit", "value": "10" }
              ]
            }
          }
        },
        {
          "name": "Sort by price",
          "request": {
            "method": "GET",
            "url": {
              "raw": "{{baseUrl}}/products?sort=price_asc",
              "host": ["{{baseUrl}}"],
              "path": ["products"],
              "query": [{ "key": "sort", "value": "price_asc" }]
            }
          }
        },
        {
          "name": "Get invalid product (expect 404)",
          "event": [
            {
              "listen": "test",
              "script": {
                "type": "text/javascript",
                "exec": [
                  "pm.test('Unknown product returns 404', () => pm.response.to.have.status(404));"
                ]
              }
            }
          ],
          "request": {
            "method": "GET",
            "url": { "raw": "{{baseUrl}}/products/999999", "host": ["{{baseUrl}}"], "path": ["products", "999999"] }
          }
        }
      ]
    },
    {
      "name": "Orders",
      "item": [
        {
          "name": "Create order (requires auth)",
          "event": [
            {
              "listen": "test",
              "script": {
                "type": "text/javascript",
                "exec": [
                  "pm.test('Status is 201', () => pm.response.to.have.status(201));"
                ]
              }
            }
          ],
          "request": {
            "method": "POST",
            "header": [
              { "key": "Content-Type", "value": "application/json" },
              { "key": "Authorization", "value": "Bearer {{accessToken}}" }
            ],
            "body": { "mode": "raw", "raw": "{\n  \"productId\": {{productId}},\n  \"quantity\": 1\n}" },
            "url": { "raw": "{{baseUrl}}/orders", "host": ["{{baseUrl}}"], "path": ["orders"] }
          }
        },
        {
          "name": "Create order without auth (expect 401)",
          "event": [
            {
              "listen": "test",
              "script": {
                "type": "text/javascript",
                "exec": [
                  "pm.test('Unauthenticated order returns 401', () => pm.response.to.have.status(401));"
                ]
              }
            }
          ],
          "request": {
            "method": "POST",
            "header": [{ "key": "Content-Type", "value": "application/json" }],
            "body": { "mode": "raw", "raw": "{\n  \"productId\": {{productId}},\n  \"quantity\": 1\n}" },
            "url": { "raw": "{{baseUrl}}/orders", "host": ["{{baseUrl}}"], "path": ["orders"] }
          }
        },
        {
          "name": "List orders",
          "request": {
            "method": "GET",
            "header": [{ "key": "Authorization", "value": "Bearer {{accessToken}}" }],
            "url": { "raw": "{{baseUrl}}/orders", "host": ["{{baseUrl}}"], "path": ["orders"] }
          }
        }
      ]
    }
  ]
}
