Skip to content

Commit 9fa0e97

Browse files
AchoArnoldCopilot
andcommitted
refactor(tests): migrate emulator from net/http to Fiber v3
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
1 parent 5e99ed8 commit 9fa0e97

7 files changed

Lines changed: 106 additions & 49 deletions

File tree

tests/emulator/Dockerfile

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,10 @@
11
FROM golang:1.22-alpine AS builder
22

33
WORKDIR /app
4-
COPY go.mod ./
4+
COPY go.mod go.sum ./
5+
RUN go mod download
56
COPY *.go ./
6-
RUN go build -o emulator .
7+
RUN CGO_ENABLED=0 go build -o emulator .
78

89
FROM alpine:latest
910
RUN apk --no-cache add wget

tests/emulator/emulator.exe

13 MB
Binary file not shown.

tests/emulator/fcm_handler.go

Lines changed: 11 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -1,38 +1,24 @@
11
package main
22

33
import (
4-
"encoding/json"
5-
"io"
64
"log"
7-
"net/http"
5+
6+
"github.com/gofiber/fiber/v3"
87
)
98

109
// HandleFCM receives FCM push notification requests from the API.
1110
// After receiving a push, it triggers SENT and DELIVERED events asynchronously.
12-
func (e *Emulator) HandleFCM(w http.ResponseWriter, r *http.Request) {
13-
log.Printf("[FCM] %s %s", r.Method, r.URL.Path)
14-
15-
body, err := io.ReadAll(r.Body)
16-
if err != nil {
17-
log.Printf("[FCM] error reading body: %v", err)
18-
http.Error(w, "bad request", http.StatusBadRequest)
19-
return
20-
}
21-
defer r.Body.Close()
22-
23-
log.Printf("[FCM] body: %s", string(body))
11+
func (e *Emulator) HandleFCM(c fiber.Ctx) error {
12+
log.Printf("[FCM] %s %s", c.Method(), c.Path())
13+
log.Printf("[FCM] body: %s", string(c.Body()))
2414

25-
var fcmRequest map[string]interface{}
26-
if err := json.Unmarshal(body, &fcmRequest); err != nil {
27-
log.Printf("[FCM] error parsing body: %v", err)
28-
}
29-
30-
response := map[string]interface{}{
15+
// Respond with a fake FCM success response
16+
err := c.JSON(fiber.Map{
3117
"name": "projects/httpsms-test/messages/fake-message-id",
32-
}
33-
34-
w.Header().Set("Content-Type", "application/json")
35-
_ = json.NewEncoder(w).Encode(response)
18+
})
3619

20+
// Fire events asynchronously (mimics phone receiving push and responding)
3721
go e.ProcessOutstandingMessages()
22+
23+
return err
3824
}

tests/emulator/go.mod

Lines changed: 24 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,26 @@
11
module github.com/NdoleStudio/httpsms/tests/emulator
22

3-
go 1.22
3+
go 1.23
4+
5+
require github.com/gofiber/fiber/v3 v3.0.0-beta.4
6+
7+
require (
8+
github.com/andybalholm/brotli v1.1.1 // indirect
9+
github.com/fxamacker/cbor/v2 v2.7.0 // indirect
10+
github.com/gofiber/schema v1.2.0 // indirect
11+
github.com/gofiber/utils/v2 v2.0.0-beta.7 // indirect
12+
github.com/google/uuid v1.6.0 // indirect
13+
github.com/klauspost/compress v1.17.11 // indirect
14+
github.com/mattn/go-colorable v0.1.13 // indirect
15+
github.com/mattn/go-isatty v0.0.20 // indirect
16+
github.com/philhofer/fwd v1.1.3-0.20240916144458-20a13a1f6b7c // indirect
17+
github.com/tinylib/msgp v1.2.5 // indirect
18+
github.com/valyala/bytebufferpool v1.0.0 // indirect
19+
github.com/valyala/fasthttp v1.58.0 // indirect
20+
github.com/valyala/tcplisten v1.0.0 // indirect
21+
github.com/x448/float16 v0.8.4 // indirect
22+
golang.org/x/crypto v0.31.0 // indirect
23+
golang.org/x/net v0.31.0 // indirect
24+
golang.org/x/sys v0.28.0 // indirect
25+
golang.org/x/text v0.21.0 // indirect
26+
)

tests/emulator/go.sum

Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,51 @@
1+
github.com/andybalholm/brotli v1.1.1 h1:PR2pgnyFznKEugtsUo0xLdDop5SKXd5Qf5ysW+7XdTA=
2+
github.com/andybalholm/brotli v1.1.1/go.mod h1:05ib4cKhjx3OQYUY22hTVd34Bc8upXjOLL2rKwwZBoA=
3+
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
4+
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
5+
github.com/fxamacker/cbor/v2 v2.7.0 h1:iM5WgngdRBanHcxugY4JySA0nk1wZorNOpTgCMedv5E=
6+
github.com/fxamacker/cbor/v2 v2.7.0/go.mod h1:pxXPTn3joSm21Gbwsv0w9OSA2y1HFR9qXEeXQVeNoDQ=
7+
github.com/gofiber/fiber/v3 v3.0.0-beta.4 h1:KzDSavvhG7m81NIsmnu5l3ZDbVS4feCidl4xlIfu6V0=
8+
github.com/gofiber/fiber/v3 v3.0.0-beta.4/go.mod h1:/WFUoHRkZEsGHyy2+fYcdqi109IVOFbVwxv1n1RU+kk=
9+
github.com/gofiber/schema v1.2.0 h1:j+ZRrNnUa/0ZuWrn/6kAtAufEr4jCJ+JuTURAMxNSZg=
10+
github.com/gofiber/schema v1.2.0/go.mod h1:YYwj01w3hVfaNjhtJzaqetymL56VW642YS3qZPhuE6c=
11+
github.com/gofiber/utils/v2 v2.0.0-beta.7 h1:NnHFrRHvhrufPABdWajcKZejz9HnCWmT/asoxRsiEbQ=
12+
github.com/gofiber/utils/v2 v2.0.0-beta.7/go.mod h1:J/M03s+HMdZdvhAeyh76xT72IfVqBzuz/OJkrMa7cwU=
13+
github.com/google/uuid v1.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0=
14+
github.com/google/uuid v1.6.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
15+
github.com/klauspost/compress v1.17.11 h1:In6xLpyWOi1+C7tXUUWv2ot1QvBjxevKAaI6IXrJmUc=
16+
github.com/klauspost/compress v1.17.11/go.mod h1:pMDklpSncoRMuLFrf1W9Ss9KT+0rH90U12bZKk7uwG0=
17+
github.com/mattn/go-colorable v0.1.13 h1:fFA4WZxdEF4tXPZVKMLwD8oUnCTTo08duU7wxecdEvA=
18+
github.com/mattn/go-colorable v0.1.13/go.mod h1:7S9/ev0klgBDR4GtXTXX8a3vIGJpMovkB8vQcUbaXHg=
19+
github.com/mattn/go-isatty v0.0.16/go.mod h1:kYGgaQfpe5nmfYZH+SKPsOc2e4SrIfOl2e/yFXSvRLM=
20+
github.com/mattn/go-isatty v0.0.20 h1:xfD0iDuEKnDkl03q4limB+vH+GxLEtL/jb4xVJSWWEY=
21+
github.com/mattn/go-isatty v0.0.20/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y=
22+
github.com/philhofer/fwd v1.1.3-0.20240916144458-20a13a1f6b7c h1:dAMKvw0MlJT1GshSTtih8C2gDs04w8dReiOGXrGLNoY=
23+
github.com/philhofer/fwd v1.1.3-0.20240916144458-20a13a1f6b7c/go.mod h1:RqIHx9QI14HlwKwm98g9Re5prTQ6LdeRQn+gXJFxsJM=
24+
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
25+
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
26+
github.com/stretchr/testify v1.10.0 h1:Xv5erBjTwe/5IxqUQTdXv5kgmIvbHo3QQyRwhJsOfJA=
27+
github.com/stretchr/testify v1.10.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY=
28+
github.com/tinylib/msgp v1.2.5 h1:WeQg1whrXRFiZusidTQqzETkRpGjFjcIhW6uqWH09po=
29+
github.com/tinylib/msgp v1.2.5/go.mod h1:ykjzy2wzgrlvpDCRc4LA8UXy6D8bzMSuAF3WD57Gok0=
30+
github.com/valyala/bytebufferpool v1.0.0 h1:GqA5TC/0021Y/b9FG4Oi9Mr3q7XYx6KllzawFIhcdPw=
31+
github.com/valyala/bytebufferpool v1.0.0/go.mod h1:6bBcMArwyJ5K/AmCkWv1jt77kVWyCJ6HpOuEn7z0Csc=
32+
github.com/valyala/fasthttp v1.58.0 h1:GGB2dWxSbEprU9j0iMJHgdKYJVDyjrOwF9RE59PbRuE=
33+
github.com/valyala/fasthttp v1.58.0/go.mod h1:SYXvHHaFp7QZHGKSHmoMipInhrI5StHrhDTYVEjK/Kw=
34+
github.com/valyala/tcplisten v1.0.0 h1:rBHj/Xf+E1tRGZyWIWwJDiRY0zc1Js+CV5DqwacVSA8=
35+
github.com/valyala/tcplisten v1.0.0/go.mod h1:T0xQ8SeCZGxckz9qRXTfG43PvQ/mcWh7FwZEA7Ioqkc=
36+
github.com/x448/float16 v0.8.4 h1:qLwI1I70+NjRFUR3zs1JPUCgaCXSh3SW62uAKT1mSBM=
37+
github.com/x448/float16 v0.8.4/go.mod h1:14CWIYCyZA/cWjXOioeEpHeN/83MdbZDRQHoFcYsOfg=
38+
github.com/xyproto/randomstring v1.0.5 h1:YtlWPoRdgMu3NZtP45drfy1GKoojuR7hmRcnhZqKjWU=
39+
github.com/xyproto/randomstring v1.0.5/go.mod h1:rgmS5DeNXLivK7YprL0pY+lTuhNQW3iGxZ18UQApw/E=
40+
golang.org/x/crypto v0.31.0 h1:ihbySMvVjLAeSH1IbfcRTkD/iNscyz8rGzjF/E5hV6U=
41+
golang.org/x/crypto v0.31.0/go.mod h1:kDsLvtWBEx7MV9tJOj9bnXsPbxwJQ6csT/x4KIN4Ssk=
42+
golang.org/x/net v0.31.0 h1:68CPQngjLL0r2AlUKiSxtQFKvzRVbnzLwMUn5SzcLHo=
43+
golang.org/x/net v0.31.0/go.mod h1:P4fl1q7dY2hnZFxEk4pPSkDHF+QqjitcnDjUQyMM+pM=
44+
golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
45+
golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
46+
golang.org/x/sys v0.28.0 h1:Fksou7UEQUWlKvIdsqzJmUmCX3cZuD2+P3XyyzwMhlA=
47+
golang.org/x/sys v0.28.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
48+
golang.org/x/text v0.21.0 h1:zyQAAkrwaneQ066sspRyJaG9VNi/YJ1NfzcGB3hZ/qo=
49+
golang.org/x/text v0.21.0/go.mod h1:4IBbMaMmOPCJ8SecivzSH54+73PCFmPWxNTLm+vZkEQ=
50+
gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
51+
gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=

tests/emulator/main.go

Lines changed: 11 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -2,8 +2,9 @@ package main
22

33
import (
44
"log"
5-
"net/http"
65
"os"
6+
7+
"github.com/gofiber/fiber/v3"
78
)
89

910
func main() {
@@ -14,26 +15,24 @@ func main() {
1415
port = "9090"
1516
}
1617

17-
mux := http.NewServeMux()
18+
app := fiber.New()
1819

19-
mux.HandleFunc("/health", func(w http.ResponseWriter, r *http.Request) {
20-
w.WriteHeader(http.StatusOK)
21-
_, _ = w.Write([]byte("ok"))
20+
app.Get("/health", func(c fiber.Ctx) error {
21+
return c.SendString("ok")
2222
})
2323

24-
mux.HandleFunc("/token", emulator.HandleToken)
25-
mux.HandleFunc("/v1/projects/", emulator.HandleFCM)
24+
app.All("/token", emulator.HandleToken)
25+
app.All("/v1/projects/:project/messages\\:send", emulator.HandleFCM)
2626

27-
mux.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) {
28-
log.Printf("[CATCH-ALL] %s %s", r.Method, r.URL.Path)
29-
w.WriteHeader(http.StatusOK)
30-
_, _ = w.Write([]byte("ok"))
27+
app.Use(func(c fiber.Ctx) error {
28+
log.Printf("[CATCH-ALL] %s %s", c.Method(), c.Path())
29+
return c.SendString("ok")
3130
})
3231

3332
log.Printf("Emulator starting on port %s", port)
3433
log.Printf("API_BASE_URL: %s", emulator.apiBaseURL)
3534

36-
if err := http.ListenAndServe(":"+port, mux); err != nil {
35+
if err := app.Listen(":" + port); err != nil {
3736
log.Fatalf("server failed: %v", err)
3837
}
3938
}

tests/emulator/token_handler.go

Lines changed: 6 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,22 +1,19 @@
11
package main
22

33
import (
4-
"encoding/json"
54
"log"
6-
"net/http"
5+
6+
"github.com/gofiber/fiber/v3"
77
)
88

99
// HandleToken serves a fake OAuth2 token response.
1010
// The Firebase SDK calls this endpoint (from token_uri in credentials) before sending FCM messages.
11-
func (e *Emulator) HandleToken(w http.ResponseWriter, r *http.Request) {
12-
log.Printf("[TOKEN] %s %s", r.Method, r.URL.Path)
11+
func (e *Emulator) HandleToken(c fiber.Ctx) error {
12+
log.Printf("[TOKEN] %s %s", c.Method(), c.Path())
1313

14-
response := map[string]interface{}{
14+
return c.JSON(fiber.Map{
1515
"access_token": "fake-access-token",
1616
"token_type": "Bearer",
1717
"expires_in": 3600,
18-
}
19-
20-
w.Header().Set("Content-Type", "application/json")
21-
_ = json.NewEncoder(w).Encode(response)
18+
})
2219
}

0 commit comments

Comments
 (0)