{"id":34132431,"url":"https://github.com/kajf/bozr","last_synced_at":"2025-12-15T01:01:21.934Z","repository":{"id":42664887,"uuid":"62330022","full_name":"kajf/bozr","owner":"kajf","description":"Minimalistic CLI tool to perform REST API tests based on JSON DSL","archived":false,"fork":false,"pushed_at":"2024-02-21T10:06:43.000Z","size":11753,"stargazers_count":31,"open_issues_count":18,"forks_count":9,"subscribers_count":5,"default_branch":"master","last_synced_at":"2024-06-19T00:31:56.136Z","etag":null,"topics":["dsl","json","json-description","rest-api","testing"],"latest_commit_sha":null,"homepage":"","language":"Go","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/kajf.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2016-06-30T17:29:21.000Z","updated_at":"2024-05-04T08:59:30.000Z","dependencies_parsed_at":"2024-06-19T00:14:18.168Z","dependency_job_id":"61b96336-7dde-4cc9-9752-874b04445ea2","html_url":"https://github.com/kajf/bozr","commit_stats":null,"previous_names":["kajf/t-rest"],"tags_count":23,"template":false,"template_full_name":null,"purl":"pkg:github/kajf/bozr","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/kajf%2Fbozr","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/kajf%2Fbozr/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/kajf%2Fbozr/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/kajf%2Fbozr/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/kajf","download_url":"https://codeload.github.com/kajf/bozr/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/kajf%2Fbozr/sbom","scorecard":{"id":547959,"data":{"date":"2025-08-11","repo":{"name":"github.com/kajf/bozr","commit":"9f140455a01e3c118fab4e771b77159d399f8d55"},"scorecard":{"version":"v5.2.1-40-gf6ed084d","commit":"f6ed084d17c9236477efd66e5b258b9d4cc7b389"},"score":4,"checks":[{"name":"Maintained","score":0,"reason":"0 commit(s) and 0 issue activity found in the last 90 days -- score normalized to 0","details":null,"documentation":{"short":"Determines if the project is \"actively maintained\".","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#maintained"}},{"name":"Code-Review","score":0,"reason":"Found 0/30 approved changesets -- score normalized to 0","details":null,"documentation":{"short":"Determines if the project requires human code review before pull requests (aka merge requests) are merged.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#code-review"}},{"name":"Dangerous-Workflow","score":10,"reason":"no dangerous workflow patterns detected","details":null,"documentation":{"short":"Determines if the project's GitHub Action workflows avoid dangerous patterns.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#dangerous-workflow"}},{"name":"CII-Best-Practices","score":0,"reason":"no effort to earn an OpenSSF best practices badge detected","details":null,"documentation":{"short":"Determines if the project has an OpenSSF (formerly CII) Best Practices Badge.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#cii-best-practices"}},{"name":"Security-Policy","score":0,"reason":"security policy file not detected","details":["Warn: no security policy file detected","Warn: no security file to analyze","Warn: no security file to analyze","Warn: no security file to analyze"],"documentation":{"short":"Determines if the project has published a security policy.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#security-policy"}},{"name":"Token-Permissions","score":0,"reason":"detected GitHub workflow tokens with excessive permissions","details":["Warn: no topLevel permission defined: .github/workflows/ci-master.yml:1","Warn: no topLevel permission defined: .github/workflows/codeql-analysis.yml:1","Warn: no topLevel permission defined: .github/workflows/release-tag.yml:1","Info: no jobLevel write permissions found"],"documentation":{"short":"Determines if the project's workflows follow the principle of least privilege.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#token-permissions"}},{"name":"SAST","score":10,"reason":"SAST tool detected: CodeQL","details":["Info: SAST configuration detected: CodeQL","Warn: no pull requests merged into dev branch"],"documentation":{"short":"Determines if the project uses static code analysis.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#sast"}},{"name":"Fuzzing","score":0,"reason":"project is not fuzzed","details":["Warn: no fuzzer integrations found"],"documentation":{"short":"Determines if the project uses fuzzing.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#fuzzing"}},{"name":"License","score":10,"reason":"license file detected","details":["Info: project has a license file: LICENSE:0","Info: FSF or OSI recognized license: MIT License: LICENSE:0"],"documentation":{"short":"Determines if the project has defined a license.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#license"}},{"name":"Packaging","score":10,"reason":"packaging workflow detected","details":["Info: Project packages its releases by way of GitHub Actions.: .github/workflows/release-tag.yml:8"],"documentation":{"short":"Determines if the project is published as a package that others can easily download, install, easily update, and uninstall.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#packaging"}},{"name":"Binary-Artifacts","score":10,"reason":"no binaries found in the repo","details":null,"documentation":{"short":"Determines if the project has generated executable (binary) artifacts in the source repository.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#binary-artifacts"}},{"name":"Branch-Protection","score":0,"reason":"branch protection not enabled on development/release branches","details":["Warn: branch protection not enabled for branch 'master'"],"documentation":{"short":"Determines if the default and release branches are protected with GitHub's branch protection settings.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#branch-protection"}},{"name":"Signed-Releases","score":0,"reason":"Project has not signed or included provenance with any releases.","details":["Warn: release artifact v0.9.6 not signed: https://api.github.com/repos/kajf/bozr/releases/200104199","Warn: release artifact v0.9.5 not signed: https://api.github.com/repos/kajf/bozr/releases/79924451","Warn: release artifact v0.9.4 not signed: https://api.github.com/repos/kajf/bozr/releases/79907201","Warn: release artifact v0.9.3 not signed: https://api.github.com/repos/kajf/bozr/releases/51702393","Warn: release artifact v0.9.2 not signed: https://api.github.com/repos/kajf/bozr/releases/48663422","Warn: release artifact v0.9.6 does not have provenance: https://api.github.com/repos/kajf/bozr/releases/200104199","Warn: release artifact v0.9.5 does not have provenance: https://api.github.com/repos/kajf/bozr/releases/79924451","Warn: release artifact v0.9.4 does not have provenance: https://api.github.com/repos/kajf/bozr/releases/79907201","Warn: release artifact v0.9.3 does not have provenance: https://api.github.com/repos/kajf/bozr/releases/51702393","Warn: release artifact v0.9.2 does not have provenance: https://api.github.com/repos/kajf/bozr/releases/48663422"],"documentation":{"short":"Determines if the project cryptographically signs release artifacts.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#signed-releases"}},{"name":"Pinned-Dependencies","score":0,"reason":"dependency not pinned by hash detected -- score normalized to 0","details":["Warn: GitHub-owned GitHubAction not pinned by hash: .github/workflows/ci-master.yml:15: update your workflow using https://app.stepsecurity.io/secureworkflow/kajf/bozr/ci-master.yml/master?enable=pin","Warn: GitHub-owned GitHubAction not pinned by hash: .github/workflows/ci-master.yml:21: update your workflow using https://app.stepsecurity.io/secureworkflow/kajf/bozr/ci-master.yml/master?enable=pin","Warn: GitHub-owned GitHubAction not pinned by hash: .github/workflows/codeql-analysis.yml:33: update your workflow using https://app.stepsecurity.io/secureworkflow/kajf/bozr/codeql-analysis.yml/master?enable=pin","Warn: GitHub-owned GitHubAction not pinned by hash: .github/workflows/codeql-analysis.yml:46: update your workflow using https://app.stepsecurity.io/secureworkflow/kajf/bozr/codeql-analysis.yml/master?enable=pin","Warn: GitHub-owned GitHubAction not pinned by hash: .github/workflows/codeql-analysis.yml:57: update your workflow using https://app.stepsecurity.io/secureworkflow/kajf/bozr/codeql-analysis.yml/master?enable=pin","Warn: GitHub-owned GitHubAction not pinned by hash: .github/workflows/codeql-analysis.yml:71: update your workflow using https://app.stepsecurity.io/secureworkflow/kajf/bozr/codeql-analysis.yml/master?enable=pin","Warn: GitHub-owned GitHubAction not pinned by hash: .github/workflows/release-tag.yml:11: update your workflow using https://app.stepsecurity.io/secureworkflow/kajf/bozr/release-tag.yml/master?enable=pin","Warn: GitHub-owned GitHubAction not pinned by hash: .github/workflows/release-tag.yml:15: update your workflow using https://app.stepsecurity.io/secureworkflow/kajf/bozr/release-tag.yml/master?enable=pin","Warn: third-party GitHubAction not pinned by hash: .github/workflows/release-tag.yml:19: update your workflow using https://app.stepsecurity.io/secureworkflow/kajf/bozr/release-tag.yml/master?enable=pin","Info:   0 out of   8 GitHub-owned GitHubAction dependencies pinned","Info:   0 out of   1 third-party GitHubAction dependencies pinned"],"documentation":{"short":"Determines if the project has declared and pinned the dependencies of its build process.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#pinned-dependencies"}},{"name":"Vulnerabilities","score":9,"reason":"1 existing vulnerabilities detected","details":["Warn: Project is vulnerable to: GO-2022-0493 / GHSA-p782-xgp4-8hr8"],"documentation":{"short":"Determines if the project has open, known unfixed vulnerabilities.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#vulnerabilities"}}]},"last_synced_at":"2025-08-20T10:01:00.553Z","repository_id":42664887,"created_at":"2025-08-20T10:01:00.553Z","updated_at":"2025-08-20T10:01:00.553Z"},"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":27741155,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","status":"online","status_checked_at":"2025-12-14T02:00:11.348Z","response_time":56,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["dsl","json","json-description","rest-api","testing"],"created_at":"2025-12-15T01:00:38.819Z","updated_at":"2025-12-15T01:01:21.908Z","avatar_url":"https://github.com/kajf.png","language":"Go","readme":"![Bozr](https://raw.githubusercontent.com/kajf/bozr/master/assets/bozr.png)\n\nMinimalistic tool to perform API tests based on JSON description\n\n[![Build Status](https://travis-ci.org/kajf/bozr.svg?branch=master)](https://travis-ci.org/kajf/bozr?branch=master)\n[![Go Report Card](https://goreportcard.com/badge/github.com/kajf/bozr)](https://goreportcard.com/report/github.com/kajf/bozr)\n\n## Usage\n\n```bash\nbozr [OPTIONS] (DIR|FILE)\n\nOptions:\n  -H, --host      Base URL prefix for test calls\n  -w, --workers   Execute in parallel with specified number of workers\n      --rewrite-response-location Rewrite response header (Location) before it get checked against expectations\n      --header    Extra header to add to each request\n      --throttle  Execute no more than specified number of requests per second (in suite)\n  -h, --help      Print usage\n  -i, --info      Enable info mode. Print request and response details.\n  -d, --debug     Enable debug mode\n      --junit     Enable junit xml reporter\n  -v, --version   Print version information and quit\n\nExamples:\n  bozr ./examples/suite-file.suite.json\n  bozr -w 2 ./examples\n  bozr -H http://example.com ./examples\n  bozr --header \"X-Test-LaunchID: RDQ1341\" ./examples\n```\n\nUsage [demo](https://asciinema.org/a/85699)\n\n## Installation\n\nIf you are using Linux, macOS or WSL you can use the following command\n\n```sh\ncurl -fsSL https://raw.github.com/kajf/bozr/master/tools/install.sh | sudo bash\n```\n\nOtherwise, you need to download the [latest binary release](https://github.com/kajf/bozr/releases) and unpack it manually.\n\n## Test Suite Format\n\nTest suite (suite_name.suite.json)\n\n    ├ Test A [test case]\n    |   ├ name\n    |   ├ ignore [ignore test due to a specified reason]\n    |   ├ args [value(s) for placeholders to use in request params, headers or body]\n    │   ├ Call one\n    |   |   ├ args\n    │   │   ├ on [single http request]\n    │   │   ├ expect [http response asserts: code, headers, body, schema, etc.]\n    │   │   └ remember [optionally remember variable(s) for the next call to use in request params, headers or body]\n    │   └ Call two\n    |       ├ args\n    │       ├ on\n    │       ├ expect\n    │       └ remember\n    └ Test B\n        ├ name\n        └ Call one\n            ├ args\n            ├ on\n            ├ expect\n            └ remember\n\n### Suite file extension\n\nAll suites must have `.suite.json` extension.\n\nIf you want to temporary disable suite, change extension to `.xsuite.json`. Bozr does not execute ignored suites, but reports all test cases as skipped.\n\n### Section 'On'\n\nRepresents http request parameters\n\n```json\n{\n  \"on\": {\n    \"method\": \"POST\",\n    \"url\": \"/api/company/users\",\n    \"headers\": {\n      \"Accept\": \"application/json\",\n      \"Content-Type\": \"application/json\"\n    },\n    \"params\": {\n      \"role\": \"admin\"\n    },\n    \"bodyFile\": \"admins.json\"\n  }\n}\n```\n\n| Field    | Description                                                          |\n| -------- | -------------------------------------------------------------------- |\n| method   | HTTP method                                                          |\n| url      | HTTP request URL                                                     |\n| headers  | HTTP request headers                                                 |\n| params   | HTTP query params                                                    |\n| bodyFile | File to send as a request payload (path relative to test suite json) |\n| body     | String or JSON object to send as a request payload                   |\n| options  | Fine tuning of request. See details in #Options chapter              |\n\n#### Options\n\n| Field           | Description                           |\n| --------------- | ------------------------------------- |\n| followRedirects | Follow HTTP redirects (default: true) |\n\n### Section 'Expect'\n\nRepresents assertions for http response of the test call.\n\nResponse:\n\n```json\n{\n  \"errors\": [{ \"code\": \"FOO\" }]\n}\n```\n\nPassing Test:\n\n```json\n{\n  \"expect\": {\n    \"statusCode\": 200,\n    \"contentType\": \"application/json\",\n    \"bodyPath\": {\n      \"errors.size()\": 1\n    }\n  }\n}\n```\n\n| Assertion      | Description                                                                                                                                             | Example                                          |\n| -------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------ |\n| statusCode     | Expected http response header 'Status Code'                                                                                                             | 200                                              |\n| contentType    | Expected http response 'Content-Type'                                                                                                                   | application/json                                 |\n| bodySchemaFile | Path to json schema to validate response body (path relative to test suite file)                                                                        | login-schema.json                                |\n| bodySchemaURI  | URI to json schema to validate response body (absolute or relative to the host)                                                                         | http://example.com/api/scheme/login-schema.json  |\n| bodySchema     | Embedded json schema to validate response body                                                                                                          | { \"type\": \"object\", \"required\": [ \"field_name\" ] |\n| body           | Expected body structure and values. Not strict, e.g. full equality is not required. Response may contain more properties. But all specified must match. |                                                  |\n| exactBody      | Expected exact body structure and values. Specified body should fully match response. Not specified properties returned in response will cause error.   |                                                  |\n| bodyPath       | Body matchers: equals, search, size                                                                                                                     |                                                  |\n| absent         | Paths that are NOT expected to be in response                                                                                                           | ['user.cardNumber', 'user.password']             |\n| headers        | Expected http headers, specified as a key-value pairs.                                                                                                  |                                                  |\n\n#### 'Expect' body matchers\n\nResponse:\n\n```json\n{\n  \"users\": [\n    { \"name\": \"John\", \"surname\": \"Wayne\", \"age\": 38 },\n    { \"name\": \"John\", \"surname\": \"Doe\", \"age\": 12 }\n  ],\n  \"errors\": []\n}\n```\n\nCould be used to partially match response body:\n\n```json\n{\n  \"expect\": {\n    \"body\": {\n      \"users\": [{ \"name\": \"John\", \"age\": 38 }]\n    }\n  }\n}\n```\n\nExact match (no new properties in the response) can be checked using \"exactBody\".\n\n#### 'Expect' body path matchers\n\nResponse:\n\n```json\n{\n  \"users\": [\n    { \"name\": \"John\", \"surname\": \"Wayne\", \"age\": 38 },\n    { \"name\": \"John\", \"surname\": \"Doe\", \"age\": 12 }\n  ],\n  \"errors\": []\n}\n```\n\nPassing Test `expect` fragment:\n\n```json\n{\n  \"expect\": {\n    \"bodyPath\": {\n      \"users.1.surname\": \"Doe\",\n      \"users.name\": \"John\",\n      \"users\": {\n        \"name\": \"John\",\n        \"age\": 12\n      },\n      \"errors.size()\": 0\n    }\n  }\n}\n```\n\n| Type   | Assertion                                                                             | Example                                               |\n| ------ | ------------------------------------------------------------------------------------- | ----------------------------------------------------- |\n| equals | Root 'users' array zero element has value of 'id' equal to '123'                      | \"users.0.id\" : \"123\"                                  |\n| search | Root 'users' array contains element(s) with 'name' equal to 'Jack' or 'Dan' and 'Ron' | \"users.name\" : \"Jack\" or \"users.name\" : [\"Dan\",\"Ron\"] |\n| size   | Root 'company' element has 'users' array with '22' elements within 'buildings' array  | \"company.buildings.users.size()\" : 22                 |\n\nXML:\n\n- To match attribute use `-` symbol before attribute name. E.g. `users.0.-id`\n- Namespaces are ignored\n- Only string matcher values are supported (since xml has no real data types, so everything is a string)\n\n#### 'Expect absent' body matchers\n\nRepresents paths not expected to be in response body.\nMostly used for security checks (e.g. returned user object should not contain password or credit card number fields)\nPath fromat is the same as in `expect.bodyPath` section\n\n```json\n{\n  \"expect\": {\n    \"absent\": [\"user.cardNumber\", \"user.password\"]\n  }\n}\n```\n\n### Section 'Args'\n\nSpecifies placeholder values for future reference (within test scope)\n\nPlaceholder values could be used inside `on.url`, `on.params`, `on.headers`, `on.body`, `on.bodyFile`, `expect.headers`, `expect.body`, `expect.bodyPath` sections.\n\n```json\n{\n  \"args\": {\n    \"currencyCode\": \"USD\",\n    \"magicNumber\": \"12f\"\n  }\n}\n```\n\nGiven `args` are defined like above, placeholders {currencyCode} and {magicNumber} may be used in correspondent test case.\n\nexample_bodyfile.json\n\n```json\n{\n  \"bankAccount\": {\n    \"currency\": \"{currencyCode}\",\n    \"amount\": 1000,\n    \"secret\": \"{magicNumber}\"\n  }\n}\n```\n\nResulting data will contain \"USD\" and \"12f\" values instead of placeholders.\n\n```json\n{\n  \"bankAccount\": {\n    \"currency\": \"USD\",\n    \"amount\": 1000,\n    \"secret\": \"12f\"\n  }\n}\n```\n\n```json\n{\n  \"on\": {\n    \"method\": \"GET\",\n    \"url\": \"{hateoas_reference}\",\n    \"headers\": {\n      \"X-Secret-Key\": \"{secret_key}\"\n    }\n  }\n}\n```\n\n**Duplicated or unused argements are reported as test failure**\n\n### Functions and data generation\n\n#### Hashes\n\n_.SHA1_ calculates SHA-1 hash of it's argument\n\n```json\n{\n  \"hash\": \"{{ .SHA1 `Username` }}\"\n}\n```\n\n_.Base64_ does [Base64](https://en.wikipedia.org/wiki/Base64) transformation on provided string\n\n```json\n{\n  \"encoded\": \"{{ .Base64 `some value` }}\"\n}\n```\n\n#### Date and time\n\n_.Now_ returns current date/time\n\n```json\n{\n  \"currentDate\": \"{{ .Now | .FormatDateTime `2006-01-02` }}\"\n}\n```\n\nIn example above 'currentDate' argument will have value of current date in yyyy-mm-dd format\n\nIt is also possible to specify IANA timezone\n\n```json\n{\n  \"currentDateInNY\": \"{{ `America/New_York` | .Now }}\"\n}\n```\n\n_.DaysFromNow_ returns date/time that is N days from now\n\n```json\n{\n  \"yesterday\": \"{{-1 | .DaysFromNow | .FormatDateTime `2006-01-02` }}\"\n}\n```\n\nIn example above 'yesterday' argument will have value of yesterday's date in yyyy-mm-dd format\n\n_.FormatDateTime_ returns string representation of date/time (useful in combination with _.Now_ or _.DaysFromNow_)\n\nFunction uses example-based format (constant date '2006-01-02T15:04:05Z07:00' used as example instead of pattern)\n\n_.CurrentTimestampSec_ returns number representing current date/time in [Unix format](https://en.wikipedia.org/wiki/Unix_time)\n\n#### SOAP\n\n_.WSSEPasswordDigest_ calculates password digest according to [Web Service Security specification](https://www.oasis-open.org/committees/download.php/13392/wss-v1.1-spec-pr-UsernameTokenProfile-01.htm)\n\n```json\n{\n  \"digest\": \"{{ .WSSEPasswordDigest `{nonce}` `{created}` `{password}` }}\"\n}\n```\n\n### Section 'Remember'\n\nSimilar to `args` section, specifies plaseholder values for future reference (within test case scope).\n\nThe difference is that values for placeholders are taken from response (syntax is similar to `expect` matchers).\n\nThere are two types of sources for values to remember: response body and headers.\n\n```json\n{\n  \"remember\": {\n    \"bodyPath\": {\n      \"createdId\": \"path.to.id\"\n    },\n    \"headers\": {\n      \"loc\": \"Location\"\n    }\n  }\n}\n```\n\nThis section allows more complex test scenarios like:\n\n- 'request login token, remember, then use remembered {token} to request some data and verify'\n- 'create resource, remember resource id from response, then use remembered {id} to delete resource'\n\n### Rewrite response location\n\n`--rewrite-response-location` flag allows to modify Location header of all response before they are passed to the expectations for verification.\nValue is a go template with the following variable available\n\n| Name                     | Value                                                                                                                                                                                   |\n| ------------------------ | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |\n| response_header_location | - \\*url.URL variable containing parsed Location header. See available methods [here](https://pkg.go.dev/net/url#URL)\u003cbr/\u003e - string if header contains relative URL or arbitrary content |\n| base_url                 | Base URL prefix for test calls. Command line argument provided with -H key                                                                                                              |\n| base_url_schema          | Schema value of the base url (http://example.com:8080 -\u003e http)                                                                                                                          |\n| base_url_host            | Host value of the base_url (http://example.com:8080 -\u003e example.com:8080)                                                                                                                |\n| base_url_hostname        | Hostname value of the base_url (http://example.com:8080 -\u003e example.com)                                                                                                                 |\n| base_url_port            | Port value of the base_url (http://example.com:8080 -\u003e 8080)                                                                                                                            |\n\nFor example to fix HATEOAS links generated by the app with HTTPS-redirect enabled while running on localhost\n\n```sh\nbozr \\\n      -H http://127.0.0.1:8080/api \\\n      --header \"X-Forwarded-Proto:https\" \\\n      --rewrite-response-location=\"{{index . \\\"ctx:base_url\\\"}}{{.response_header_location.Path}}\" \\\n      examples/rewrite-response.suite.json\n```\n\n### Using environment and context variables in tests\n\nSimilar to `args` and `remember` sections, OS environment variables could be used as placeholder values for future reference (within test case scope).\n\nGiven `MY_FILTER` environment variable exists in terminal session, the following syntax with `env` prefix enables its usage\n\n```json\n{\n  \"on\": {\n    \"url\": \"http://example.com\",\n    \"method\": \"GET\",\n    \"params\": {\n      \"filter\": \"{env:MY_FILTER}\"\n    }\n  }\n}\n```\n\nContext variables are available with `ctx` prefix\n\nList of context variables\n\n| Name              | Value                                                                      |\n| ----------------- | -------------------------------------------------------------------------- |\n| base_url          | Base URL prefix for test calls. Command line argument provided with -H key |\n| base_url_schema   | Schema value of the base url (http://example.com:8080 -\u003e http)             |\n| base_url_host     | Host value of the base_url (http://example.com:8080 -\u003e example.com:8080)   |\n| base_url_hostname | Hostname value of the base_url (http://example.com:8080 -\u003e example.com)    |\n| base_url_port     | Port value of the base_url (http://example.com:8080 -\u003e 8080)               |\n\n```json\n{\n  \"expect\": {\n    \"bodyPath\": {\n      \"_links.delete\": \"{ctx:base_url}/my-resource/123\"\n    }\n  }\n}\n```\n\n## Editor integration\n\nTo make work with test files convenient, we suggest to configure you text editors to use [this](./assets/test.schema.json) json schema. In this case editor will suggest what fields are available and highlight misspells.\n\n| Editor             | JSON Autocomplete                                                                          |\n| ------------------ | ------------------------------------------------------------------------------------------ |\n| JetBrains Tools    | [native support](https://www.jetbrains.com/help/webstorm/2016.1/json-schema.html?page=1)   |\n| Visual Studio Code | [native support](https://code.visualstudio.com/docs/languages/json#_json-schemas-settings) |\n| Vim                | [plugin](https://github.com/Quramy/vison)                                                  |\n","funding_links":[],"categories":[],"sub_categories":[],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fkajf%2Fbozr","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fkajf%2Fbozr","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fkajf%2Fbozr/lists"}