diff --git a/Makefile b/Makefile
index 4b9a344793037283a3a7ed69fc03a96a15451cf5..1bba6562d076f840df66e69bf983584fe9333b89 100644
--- a/Makefile
+++ b/Makefile
@@ -86,7 +86,7 @@ lint:
 
 staticcheck: .PHONY
 	rm -rf build/staticcheck
-	which staticcheck || go get honnef.co/go/tools/cmd/staticcheck
+	which staticcheck || go install honnef.co/go/tools/cmd/staticcheck@latest
 	mkdir -p build/staticcheck
 	ln -s "$(GO)" build/staticcheck/go
 	PATH="$(PWD)/build/staticcheck:$(PATH)" staticcheck ./...
diff --git a/server/server_test.go b/server/server_test.go
index eac143741dc0009ad74e49fa98e2b832d7564244..9d9e7a6a682d90f7155565375dffb99376aaca00 100644
--- a/server/server_test.go
+++ b/server/server_test.go
@@ -1,30 +1,59 @@
 package server
 
 import (
+	"bufio"
 	"encoding/json"
 	"github.com/stretchr/testify/assert"
 	"heckel.io/ntfy/config"
 	"net/http"
 	"net/http/httptest"
+	"path/filepath"
 	"strings"
 	"testing"
 )
 
-func TestServer_Publish(t *testing.T) {
-	s := newTestServer(t, newTestConfig())
+func TestServer_PublishAndPoll(t *testing.T) {
+	s := newTestServer(t, newTestConfig(t))
 
-	rr := httptest.NewRecorder()
-	req, _ := http.NewRequest("PUT", "/mytopic", strings.NewReader("my message"))
-	s.handle(rr, req)
+	response1 := request(t, s, "PUT", "/mytopic", "my first message")
+	msg1 := toMessage(t, response1.Body.String())
+	assert.NotEmpty(t, msg1.ID)
+	assert.Equal(t, "my first message", msg1.Message)
 
-	var m message
-	assert.Nil(t, json.NewDecoder(rr.Body).Decode(&m))
-	assert.NotEmpty(t, m.ID)
-	assert.Equal(t, "my message", m.Message)
+	response2 := request(t, s, "PUT", "/mytopic", "my second message")
+	msg2 := toMessage(t, response2.Body.String())
+	assert.NotEqual(t, msg1.ID, msg2.ID)
+	assert.NotEmpty(t, msg2.ID)
+	assert.Equal(t, "my second message", msg2.Message)
+
+	response := request(t, s, "GET", "/mytopic/json?poll=1", "")
+	messages := toMessages(t, response.Body.String())
+	assert.Equal(t, 2, len(messages))
 }
 
-func newTestConfig() *config.Config {
-	return config.New(":80")
+func TestServer_PublishAndSubscribe(t *testing.T) {
+	s := newTestServer(t, newTestConfig(t))
+
+	response1 := request(t, s, "PUT", "/mytopic", "my first message")
+	msg1 := toMessage(t, response1.Body.String())
+	assert.NotEmpty(t, msg1.ID)
+	assert.Equal(t, "my first message", msg1.Message)
+
+	response2 := request(t, s, "PUT", "/mytopic", "my second message")
+	msg2 := toMessage(t, response2.Body.String())
+	assert.NotEqual(t, msg1.ID, msg2.ID)
+	assert.NotEmpty(t, msg2.ID)
+	assert.Equal(t, "my second message", msg2.Message)
+
+	response := request(t, s, "GET", "/mytopic/json?poll=1", "")
+	messages := toMessages(t, response.Body.String())
+	assert.Equal(t, 2, len(messages))
+}
+
+func newTestConfig(t *testing.T) *config.Config {
+	conf := config.New(":80")
+	conf.CacheFile = filepath.Join(t.TempDir(), "cache.db")
+	return conf
 }
 
 func newTestServer(t *testing.T, config *config.Config) *Server {
@@ -34,3 +63,28 @@ func newTestServer(t *testing.T, config *config.Config) *Server {
 	}
 	return server
 }
+
+func request(t *testing.T, s *Server, method, url, body string) *httptest.ResponseRecorder {
+	rr := httptest.NewRecorder()
+	req, err := http.NewRequest(method, url, strings.NewReader(body))
+	if err != nil {
+		t.Fatal(err)
+	}
+	s.handle(rr, req)
+	return rr
+}
+
+func toMessages(t *testing.T, s string) []*message {
+	messages := make([]*message, 0)
+	scanner := bufio.NewScanner(strings.NewReader(s))
+	for scanner.Scan() {
+		messages = append(messages, toMessage(t, scanner.Text()))
+	}
+	return messages
+}
+
+func toMessage(t *testing.T, s string) *message {
+	var m message
+	assert.Nil(t, json.NewDecoder(strings.NewReader(s)).Decode(&m))
+	return &m
+}