ntfy

The atago project wrote these specs on its own initiative and runs them in its own CI, to exercise atago against a real program. They are not ntfy’s official test suite, and the ntfy project is not affiliated with atago.

Summary #

1 suite · 4 scenarios

Contents #

ntfy (self-hosted push notification service) #

ntfy sends push notifications over plain HTTP, which means anything that can make a request can publish — and that is both its appeal and the reason its access control matters.

The publish path is pinned with its metadata intact: a notification’s title, priority, and tags must survive as sent and come back on the JSON feed. Topics must stay isolated, so a subscriber to one topic never sees another’s messages. The bundled CLI is exercised against the same server as the raw HTTP client, so the two agree.

Access control gets the same treatment as the happy path: with a deny-all default in place, publishing is refused; after a user is created and granted access through the admin CLI, the same publish succeeds.

Source: test/e2e/thirdparty/ntfy/ntfy.atago.yaml

Scenario: the binary reports its version #

When #

ntfy --version

Then #

  • exit code is 0
  • stdout matches /ntfy version [0-9]+\.[0-9]+\.[0-9]+/

Scenario: a published notification comes back through the JSON poll feed #

Given #

  • Background service ntfy is started: ntfy serve --listen-http 127.0.0.1:18180 --base-url http://127.0.0.1:18180 --cache-file data/cache.db.
  • Fixture file data/.keep is created.

When #

# HTTP GET /v1/health
# HTTP POST /atago-alerts
# HTTP GET /atago-alerts/json?poll=1
# HTTP GET /other-topic/json?poll=1

Then #

  • after HTTP GET /v1/health:
    • HTTP status is 200
    • body at $.healthy equals true
  • after HTTP POST /atago-alerts:
    • HTTP status is 200
    • body at $.event equals message
  • after HTTP GET /atago-alerts/json?poll=1:
    • HTTP status is 200
    • body at $.title equals Backup done
    • body at $.message equals nightly backup finished
    • body at $.priority equals 4
  • after HTTP GET /other-topic/json?poll=1:
    • HTTP status is 200
    • body is empty

Scenario: the bundled CLI publishes against the same server #

Given #

  • Background service ntfy is started: ntfy serve --listen-http 127.0.0.1:18181 --base-url http://127.0.0.1:18181 --cache-file data/cache.db.
  • Fixture file data/.keep is created.

When #

ntfy publish http://127.0.0.1:18181/atago-deploys "deploy one"
ntfy publish http://127.0.0.1:18181/atago-deploys "deploy two"
# HTTP GET /atago-deploys/json?poll=1&since=all

Then #

  • after ntfy publish http://127.0.0.1:18181/atago-deploys "deploy one":
    • exit code is 0
  • after ntfy publish http://127.0.0.1:18181/atago-deploys "deploy two":
    • exit code is 0
  • after HTTP GET /atago-deploys/json?poll=1&since=all:
    • HTTP status is 200
    • body contains deploy one, deploy two

Scenario: deny-all access control locks a topic until a user is granted #

Given #

  • Background service ntfy is started: ntfy serve --listen-http 127.0.0.1:18182 --base-url http://127.0.0.1:18182 --cache-file data/cache.db --auth-file data/auth.db --auth-default-access deny-all.
  • Fixture file data/.keep is created.
  • Environment variables are set: NTFY_PASSWORD.

When #

# HTTP POST /secure-topic
ntfy user add phil
ntfy access phil secure-topic rw
# HTTP POST /secure-topic
# HTTP GET /secure-topic/json?poll=1

Then #

  • after HTTP POST /secure-topic:
    • HTTP status is 403
  • after ntfy user add phil:
    • exit code is 0
    • stdout contains user phil added
  • after ntfy access phil secure-topic rw:
    • exit code is 0
  • after HTTP POST /secure-topic:
    • HTTP status is 200
  • after HTTP GET /secure-topic/json?poll=1:
    • HTTP status is 200
    • body at $.message equals authorized message