1// SPDX-License-Identifier: AGPL-3.0-or-later
2
3package client_test
4
5import (
6 "testing"
7
8 "github.com/stretchr/testify/assert"
9 "github.com/stretchr/testify/require"
10
11 "bnema.dev/ermite/internal/adapters/client"
12)
13
14func TestNewConfig(t *testing.T) {
15 cfg, err := client.NewConfig(" HTTPS://Git.Example.com/base/ ", " ermite_abc\n")
16 require.NoError(t, err)
17 assert.Equal(t, "https://Git.Example.com/base", cfg.URL)
18 assert.Equal(t, "ermite_abc", cfg.Token)
19}
20
21func TestNewConfigUnsetTellsHowToFixIt(t *testing.T) {
22 _, err := client.NewConfig(" ", "")
23 require.Error(t, err)
24 assert.Contains(t, err.Error(), "ERMITE_URL")
25 assert.Contains(t, err.Error(), "ermite config set url")
26}
27
28func TestNewConfigRejects(t *testing.T) {
29 tests := []struct {
30 name, url, want string
31 }{
32 {"unset", "", "ERMITE_URL is not set"},
33 {"no scheme", "git.example.com", "not an http(s) URL"},
34 {"ftp", "ftp://git.example.com", "not an http(s) URL"},
35 {"no host", "https://", "has no host"},
36 {"credentials", "https://user:s3cret@git.example.com", "must not contain credentials"},
37 {"query", "https://git.example.com/?a=b", "query or a fragment"},
38 {"fragment", "https://git.example.com/#x", "query or a fragment"},
39 {"garbage", "http://[::1", "not a valid URL"},
40 }
41 for _, tt := range tests {
42 t.Run(tt.name, func(t *testing.T) {
43 _, err := client.NewConfig(tt.url, "")
44 require.Error(t, err)
45 assert.Contains(t, err.Error(), tt.want)
46 assert.NotContains(t, err.Error(), "s3cret", "credentials must never be echoed")
47 })
48 }
49}
50
51func TestInsecureTokenWarning(t *testing.T) {
52 tests := []struct {
53 url, token string
54 warn bool
55 }{
56 {"http://git.example.com", "t", true},
57 {"http://10.0.0.5:7341", "t", true},
58 {"http://git.example.com", "", false}, // nothing secret to leak
59 {"https://git.example.com", "t", false},
60 {"http://localhost:7341", "t", false},
61 {"http://127.0.0.1:7341", "t", false},
62 {"http://[::1]:7341", "t", false},
63 {"http://dev.localhost", "t", false},
64 }
65 for _, tt := range tests {
66 w := client.Config{URL: tt.url, Token: tt.token}.InsecureTokenWarning()
67 assert.Equal(t, tt.warn, w != "", "%s token=%q: %q", tt.url, tt.token, w)
68 assert.NotContains(t, w, tt.token+"_", "never echo the token")
69 }
70}
71
72func TestParseURLErrorsDoNotEchoInput(t *testing.T) {
73 for _, raw := range []string{"user:s3cret@host", "s3cret.example.com", "http://", "https://h/?k=s3cret", "http://[s3cret"} {
74 _, err := client.ParseURL(raw)
75 require.Error(t, err, raw)
76 assert.NotContains(t, err.Error(), "s3cret", raw)
77 assert.NotContains(t, err.Error(), "user:", raw)
78 }
79}