• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

gameap / gameap / 19743981475

27 Nov 2025 05:26PM UTC coverage: 72.203% (-0.007%) from 72.21%
19743981475

push

github

et-nik
fix tests

9 of 11 new or added lines in 2 files covered. (81.82%)

33 existing lines in 3 files now uncovered.

24962 of 34572 relevant lines covered (72.2%)

380.66 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

82.57
/internal/api/nodes/postnode/input.go
1
package postnode
2

3
import (
4
        "fmt"
5
        "strings"
6

7
        "github.com/gameap/gameap/internal/domain"
8
        "github.com/gameap/gameap/pkg/api"
9
        "github.com/gameap/gameap/pkg/flexible"
10
        "github.com/gameap/gameap/pkg/validation"
11
)
12

13
const (
14
        minNameLength            = 1
15
        maxNameLength            = 128
16
        maxDescriptionLength     = 1024
17
        maxLocationLength        = 128
18
        maxProviderLength        = 128
19
        maxPathLength            = 512
20
        minPortNumber            = 1
21
        maxPortNumber            = 65535
22
        maxGdaemonServerCertSize = 10 * 1024 * 1024
23
)
24

25
var (
26
        ErrNameRequired = api.NewValidationError("name is required")
27
        ErrNameTooLong  = api.NewValidationError(
28
                fmt.Sprintf("name must not exceed %d characters", maxNameLength),
29
        )
30
        ErrDescriptionTooLong = api.NewValidationError(
31
                fmt.Sprintf("description must not exceed %d characters", maxDescriptionLength),
32
        )
33
        ErrLocationRequired = api.NewValidationError("location is required")
34
        ErrLocationTooLong  = api.NewValidationError(
35
                fmt.Sprintf("location must not exceed %d characters", maxLocationLength),
36
        )
37
        ErrProviderTooLong = api.NewValidationError(
38
                fmt.Sprintf("provider must not exceed %d characters", maxProviderLength),
39
        )
40
        ErrIPRequired       = api.NewValidationError("at least one IP address is required")
41
        ErrInvalidIPAddress = api.NewValidationError("invalid IP address or hostname format")
42
        ErrOSRequired       = api.NewValidationError("os is required")
43
        ErrInvalidOS        = api.NewValidationError("os must be either 'linux' or 'windows'")
44
        ErrWorkPathRequired = api.NewValidationError("work_path is required")
45
        ErrWorkPathTooLong  = api.NewValidationError(
46
                fmt.Sprintf("work_path must not exceed %d characters", maxPathLength),
47
        )
48
        ErrSteamcmdPathTooLong = api.NewValidationError(
49
                fmt.Sprintf("steamcmd_path must not exceed %d characters", maxPathLength),
50
        )
51
        ErrGdaemonHostRequired = api.NewValidationError("gdaemon_host is required")
52
        ErrGdaemonHostTooLong  = api.NewValidationError(
53
                fmt.Sprintf("gdaemon_host must not exceed %d characters", maxNameLength),
54
        )
55
        ErrGdaemonPortRequired = api.NewValidationError("gdaemon_port is required")
56
        ErrGdaemonPortInvalid  = api.NewValidationError(
57
                fmt.Sprintf("gdaemon_port must be between %d and %d", minPortNumber, maxPortNumber),
58
        )
59
        ErrClientCertificateIDZero = api.NewValidationError("client_certificate_id must be greater than 0")
60
        ErrScriptTooLong           = api.NewValidationError("script content is too long")
61
        ErrCertificateRequired     = api.NewValidationError("gdaemon_server_cert is required")
62
)
63

64
type createDedicatedServerInput struct {
65
        Name                string        `json:"name"`
66
        Description         *string       `json:"description,omitempty"`
67
        Location            string        `json:"location"`
68
        IP                  []string      `json:"ip"`
69
        OS                  string        `json:"os"`
70
        Enabled             bool          `json:"enabled"`
71
        Provider            *string       `json:"provider,omitempty"`
72
        WorkPath            string        `json:"work_path"`
73
        SteamcmdPath        *string       `json:"steamcmd_path,omitempty"`
74
        GdaemonHost         string        `json:"gdaemon_host"`
75
        GdaemonPort         flexible.Uint `json:"gdaemon_port"`
76
        ClientCertificateID flexible.Uint `json:"client_certificate_id"`
77
        GdaemonServerCert   string        `json:"gdaemon_server_cert"`
78

79
        PreferInstallMethod *string `json:"prefer_install_method,omitempty"`
80
        ScriptInstall       *string `json:"script_install,omitempty"`
81
        ScriptReinstall     *string `json:"script_reinstall,omitempty"`
82
        ScriptUpdate        *string `json:"script_update,omitempty"`
83
        ScriptStart         *string `json:"script_start,omitempty"`
84
        ScriptPause         *string `json:"script_pause,omitempty"`
85
        ScriptUnpause       *string `json:"script_unpause,omitempty"`
86
        ScriptStop          *string `json:"script_stop,omitempty"`
87
        ScriptKill          *string `json:"script_kill,omitempty"`
88
        ScriptRestart       *string `json:"script_restart,omitempty"`
89
        ScriptStatus        *string `json:"script_status,omitempty"`
90
        ScriptStats         *string `json:"script_stats,omitempty"`
91
        ScriptGetConsole    *string `json:"script_get_console,omitempty"`
92
        ScriptSendCommand   *string `json:"script_send_command,omitempty"`
93
        ScriptDelete        *string `json:"script_delete,omitempty"`
94
}
95

96
func (in *createDedicatedServerInput) Validate() error {
20✔
97
        if in.Name == "" {
21✔
98
                return ErrNameRequired
1✔
99
        }
1✔
100
        if len(in.Name) > maxNameLength {
19✔
UNCOV
101
                return ErrNameTooLong
×
UNCOV
102
        }
×
103

104
        if in.Description != nil && len(*in.Description) > maxDescriptionLength {
19✔
UNCOV
105
                return ErrDescriptionTooLong
×
UNCOV
106
        }
×
107

108
        if in.Location == "" {
20✔
109
                return ErrLocationRequired
1✔
110
        }
1✔
111
        if len(in.Location) > maxLocationLength {
18✔
UNCOV
112
                return ErrLocationTooLong
×
UNCOV
113
        }
×
114

115
        if in.Provider != nil && len(*in.Provider) > maxProviderLength {
18✔
UNCOV
116
                return ErrProviderTooLong
×
UNCOV
117
        }
×
118

119
        if len(in.IP) == 0 {
19✔
120
                return ErrIPRequired
1✔
121
        }
1✔
122

123
        for _, ip := range in.IP {
38✔
124
                if !validation.IsValidIPOrHostname(ip) {
22✔
125
                        return ErrInvalidIPAddress
1✔
126
                }
1✔
127
        }
128

129
        if in.OS == "" {
17✔
130
                return ErrOSRequired
1✔
131
        }
1✔
132
        osLower := strings.ToLower(in.OS)
15✔
133
        if osLower != "linux" && osLower != "windows" {
16✔
134
                return ErrInvalidOS
1✔
135
        }
1✔
136

137
        if in.WorkPath == "" {
15✔
138
                return ErrWorkPathRequired
1✔
139
        }
1✔
140
        if len(in.WorkPath) > maxPathLength {
13✔
UNCOV
141
                return ErrWorkPathTooLong
×
UNCOV
142
        }
×
143

144
        if in.SteamcmdPath != nil && len(*in.SteamcmdPath) > maxPathLength {
13✔
UNCOV
145
                return ErrSteamcmdPathTooLong
×
UNCOV
146
        }
×
147

148
        if in.GdaemonHost == "" {
14✔
149
                return ErrGdaemonHostRequired
1✔
150
        }
1✔
151
        if len(in.GdaemonHost) > maxNameLength {
12✔
UNCOV
152
                return ErrGdaemonHostTooLong
×
UNCOV
153
        }
×
154

155
        if in.GdaemonPort < minPortNumber || in.GdaemonPort > maxPortNumber {
14✔
156
                return ErrGdaemonPortInvalid
2✔
157
        }
2✔
158

159
        if in.ClientCertificateID == 0 {
11✔
160
                return ErrClientCertificateIDZero
1✔
161
        }
1✔
162

163
        if len(in.GdaemonServerCert) > maxGdaemonServerCertSize {
9✔
UNCOV
164
                return api.NewValidationError("gdaemon_server_cert is too large")
×
UNCOV
165
        }
×
166

167
        if in.GdaemonServerCert == "" {
10✔
168
                return ErrCertificateRequired
1✔
169
        }
1✔
170

171
        return nil
8✔
172
}
173

174
func (in *createDedicatedServerInput) ToDomain(apiKey, certPath string) *domain.Node {
7✔
175
        return &domain.Node{
7✔
176
                Enabled:             in.Enabled,
7✔
177
                Name:                strings.TrimSpace(in.Name),
7✔
178
                OS:                  domain.ParseNodeOS(in.OS),
7✔
179
                Location:            strings.TrimSpace(in.Location),
7✔
180
                Provider:            trimStringPtr(in.Provider),
7✔
181
                IPs:                 in.IP,
7✔
182
                WorkPath:            strings.TrimSpace(in.WorkPath),
7✔
183
                SteamcmdPath:        trimStringPtr(in.SteamcmdPath),
7✔
184
                GdaemonHost:         strings.TrimSpace(in.GdaemonHost),
7✔
185
                GdaemonPort:         int(in.GdaemonPort), //nolint:gosec // Port checked in validation
7✔
186
                GdaemonAPIKey:       apiKey,
7✔
187
                GdaemonServerCert:   certPath,
7✔
188
                ClientCertificateID: in.ClientCertificateID.Uint(),
7✔
189
                PreferInstallMethod: valueOrDefault(in.PreferInstallMethod, domain.NodePreferInstallMethodAuto),
7✔
190
                ScriptInstall:       trimStringPtr(in.ScriptInstall),
7✔
191
                ScriptReinstall:     trimStringPtr(in.ScriptReinstall),
7✔
192
                ScriptUpdate:        trimStringPtr(in.ScriptUpdate),
7✔
193
                ScriptStart:         trimStringPtr(in.ScriptStart),
7✔
194
                ScriptPause:         trimStringPtr(in.ScriptPause),
7✔
195
                ScriptUnpause:       trimStringPtr(in.ScriptUnpause),
7✔
196
                ScriptStop:          trimStringPtr(in.ScriptStop),
7✔
197
                ScriptKill:          trimStringPtr(in.ScriptKill),
7✔
198
                ScriptRestart:       trimStringPtr(in.ScriptRestart),
7✔
199
                ScriptStatus:        trimStringPtr(in.ScriptStatus),
7✔
200
                ScriptStats:         trimStringPtr(in.ScriptStats),
7✔
201
                ScriptGetConsole:    trimStringPtr(in.ScriptGetConsole),
7✔
202
                ScriptSendCommand:   trimStringPtr(in.ScriptSendCommand),
7✔
203
                ScriptDelete:        trimStringPtr(in.ScriptDelete),
7✔
204
        }
7✔
205
}
7✔
206

207
func valueOrDefault[T any](ptr any, defaultValue T) T {
7✔
208
        if ptr == nil {
7✔
UNCOV
209
                return defaultValue
×
UNCOV
210
        }
×
211

212
        v, ok := ptr.(T)
7✔
213
        if !ok {
14✔
214
                return defaultValue
7✔
215
        }
7✔
216

UNCOV
217
        return v
×
218
}
219

220
func trimStringPtr(s *string) *string {
112✔
221
        if s == nil {
220✔
222
                return nil
108✔
223
        }
108✔
224

225
        trimmed := strings.TrimSpace(*s)
4✔
226

4✔
227
        return &trimmed
4✔
228
}
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc