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 Network policy: egress is allowed only to 127.0.0.1.

Scenario: the binary reports its version #

only when command -v ntfy succeeds

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 #

only when command -v ntfy succeeds

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 via ntfy
# HTTP POST /atago-alerts via ntfy
# HTTP GET /atago-alerts/json?poll=1 via ntfy
# HTTP GET /other-topic/json?poll=1 via ntfy

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 #

only when command -v ntfy succeeds

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 via ntfy2

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 #

only when command -v ntfy succeeds

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 via ntfy3
ntfy user add phil
ntfy access phil secure-topic rw
# HTTP POST /secure-topic via ntfy3
# HTTP GET /secure-topic/json?poll=1 via ntfy3

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