1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
|
package api_test
import (
"encoding/json"
"net/http"
"net/http/httptest"
"os"
"path/filepath"
"testing"
"vpnem/internal/api"
"vpnem/internal/models"
"vpnem/internal/rules"
)
func setupTestStore(t *testing.T) *rules.Store {
t.Helper()
dir := t.TempDir()
writeJSON(t, filepath.Join(dir, "servers.json"), models.ServersResponse{
Servers: []models.Server{
{Tag: "test-1", Region: "NL", Type: "socks", Server: "1.2.3.4", ServerPort: 1080},
},
})
writeJSON(t, filepath.Join(dir, "rulesets.json"), models.RuleSetManifest{
RuleSets: []models.RuleSet{
{Tag: "test-rules", Description: "test", URL: "https://example.com/test.srs", Format: "binary", Type: "domain"},
},
})
writeJSON(t, filepath.Join(dir, "version.json"), models.VersionResponse{
Version: "0.1.0", Changelog: "test",
})
os.MkdirAll(filepath.Join(dir, "rules"), 0o755)
return rules.NewStore(dir)
}
func writeJSON(t *testing.T, path string, v any) {
t.Helper()
data, err := json.MarshalIndent(v, "", " ")
if err != nil {
t.Fatal(err)
}
if err := os.WriteFile(path, data, 0o644); err != nil {
t.Fatal(err)
}
}
func TestServersEndpoint(t *testing.T) {
store := setupTestStore(t)
router := api.NewRouter(store)
req := httptest.NewRequest("GET", "/api/v1/servers", nil)
w := httptest.NewRecorder()
router.ServeHTTP(w, req)
if w.Code != http.StatusOK {
t.Fatalf("expected 200, got %d", w.Code)
}
var resp models.ServersResponse
if err := json.Unmarshal(w.Body.Bytes(), &resp); err != nil {
t.Fatalf("invalid json: %v", err)
}
if len(resp.Servers) != 1 {
t.Fatalf("expected 1 server, got %d", len(resp.Servers))
}
if resp.Servers[0].Tag != "test-1" {
t.Errorf("expected tag test-1, got %s", resp.Servers[0].Tag)
}
}
func TestRuleSetManifestEndpoint(t *testing.T) {
store := setupTestStore(t)
router := api.NewRouter(store)
req := httptest.NewRequest("GET", "/api/v1/ruleset/manifest", nil)
w := httptest.NewRecorder()
router.ServeHTTP(w, req)
if w.Code != http.StatusOK {
t.Fatalf("expected 200, got %d", w.Code)
}
var resp models.RuleSetManifest
if err := json.Unmarshal(w.Body.Bytes(), &resp); err != nil {
t.Fatalf("invalid json: %v", err)
}
if len(resp.RuleSets) != 1 {
t.Fatalf("expected 1 ruleset, got %d", len(resp.RuleSets))
}
}
func TestVersionEndpoint(t *testing.T) {
store := setupTestStore(t)
router := api.NewRouter(store)
req := httptest.NewRequest("GET", "/api/v1/version", nil)
w := httptest.NewRecorder()
router.ServeHTTP(w, req)
if w.Code != http.StatusOK {
t.Fatalf("expected 200, got %d", w.Code)
}
var resp models.VersionResponse
if err := json.Unmarshal(w.Body.Bytes(), &resp); err != nil {
t.Fatalf("invalid json: %v", err)
}
if resp.Version != "0.1.0" {
t.Errorf("expected version 0.1.0, got %s", resp.Version)
}
}
func TestMethodNotAllowed(t *testing.T) {
store := setupTestStore(t)
router := api.NewRouter(store)
req := httptest.NewRequest("POST", "/api/v1/servers", nil)
w := httptest.NewRecorder()
router.ServeHTTP(w, req)
if w.Code == http.StatusOK {
t.Fatal("POST should not return 200")
}
}
|