zrizDocsLearnSecuritySign inSign up

Test an API call and the database row

Write one zriz pipeline with two calls: a POST to your API, then a select of the new row. A check compares the row with the value that the test sent.

Draft. Guide · zz 0.4.0 or later · Updated · Plain text for agents: /docs/api-and-database-test.md

The example creates an order and then reads it from Postgres. The page Pipelines is the reference for each key.

Note: The POST writes a row. Run the test against a test system: Can a zriz test change my data?

Before you start

1. Add the API call

Do

Open .zriz/resources/target.json. zz init wrote it. Add the key headers and the action create-order, and keep the other keys as they are.

.zriz/resources/target.json:

{
  "type": "http",
  "description": "Your app under test",
  "base-url": "${env.TARGET_URL}",
  "headers": { "Content-Type": "application/json" },
  "actions": {
    "check": { "method": "GET", "path": "<health path>" },
    "create-order": { "method": "POST", "path": "<path>" }
  }
}
zz validate hello

Why

A step can call only an action that a resource file names.

You should see

{"ok":true,"command":"validate",

If not

2. Add the database

Do

Use a database account that can only read: Create a read-only Postgres user.

Add the value ORDERS_DB and the key sensitive to the file of the environment. Then make the resource file.

.zriz/environments/local.json:

{
  "values": {
    "TARGET_URL": "<base url>",
    "ORDERS_DB": "postgres://<user>:<password>@<host>:5432/<database>"
  },
  "sensitive": ["ORDERS_DB"]
}

.zriz/resources/ordersdb.json:

{
  "type": "sql",
  "connection": "${env.ORDERS_DB}",
  "read-only": true,
  "actions": {
    "order-by-mark": { "query": "SELECT <column> FROM <table> WHERE <column> = ${ctx.mark}" }
  }
}
zz validate hello

Why

A name in sensitive keeps its value on your machine. With read-only, the query cannot write.

You should see

{"ok":true,"command":"validate",

If not

3. Write the pipeline

Do

Make the pipeline file. It has three steps:

  1. set makes a unique value, mark.
  2. The call sends mark to your API.
  3. The query finds the row that has mark.

.zriz/pipelines/create-order.json:

{
  "description": "Create an order, then find its row in the database",
  "steps": [
    { "set": { "mark": "t-${gen.uuid}" } },
    {
      "call": "target/create-order",
      "body": { "<field>": "${ctx.mark}" },
      "expect": [["status", "==", 201]]
    },
    {
      "call": "ordersdb/order-by-mark",
      "expect": [["row-count", "==", 1], ["rows[0].<column>", "==", "${ctx.mark}"]]
    }
  ]
}
zz validate create-order

Why

A value of set is in ctx for each later step. Thus the query and its check read the same value that the call sent.

You should see

{"ok":true,"command":"validate",

If not

4. Run the test

Do

Start your service.

zz run create-order

Why

The run passes only when the API answers and the row is in the database.

You should see

"status":"pass"

If not

Next