1package domain
2
3import "testing"
4
5func TestRemoteSessionKeyID(t *testing.T) {
6 tests := []struct {
7 name string
8 key RemoteSessionKey
9 want SessionID
10 }{
11 {
12 name: "uses raw URL base64 components",
13 key: RemoteSessionKey{Host: "arch", Name: "hello"},
14 want: "remote:YXJjaA.aGVsbG8",
15 },
16 {
17 name: "preserves host metacharacters without delimiters",
18 key: RemoteSessionKey{Host: "build@mule:2222/path.[x]", Name: "work.1"},
19 want: "remote:YnVpbGRAbXVsZToyMjIyL3BhdGguW3hd.d29yay4x",
20 },
21 {
22 name: "supports bracketed IPv6 hosts",
23 key: RemoteSessionKey{Host: "user@[2001:db8::1]:2222", Name: "work"},
24 want: "remote:dXNlckBbMjAwMTpkYjg6OjFdOjIyMjI.d29yaw",
25 },
26 }
27
28 for _, tt := range tests {
29 t.Run(tt.name, func(t *testing.T) {
30 if got := tt.key.ID(); got != tt.want {
31 t.Fatalf("RemoteSessionKey.ID() = %q, want %q", got, tt.want)
32 }
33 if got := tt.key.ID(); got != tt.key.ID() {
34 t.Fatalf("RemoteSessionKey.ID() is unstable: %q != %q", got, tt.key.ID())
35 }
36 })
37 }
38}
39
40func TestRemoteSessionKeyIDAvoidsRawConcatenationCollisions(t *testing.T) {
41 tests := []struct {
42 name string
43 first RemoteSessionKey
44 last RemoteSessionKey
45 }{
46 {
47 name: "host component delimiter",
48 first: RemoteSessionKey{Host: "arch.work", Name: "shell"},
49 last: RemoteSessionKey{Host: "arch", Name: "work.shell"},
50 },
51 }
52
53 for _, tt := range tests {
54 t.Run(tt.name, func(t *testing.T) {
55 if tt.first.Host+"."+tt.first.Name != tt.last.Host+"."+tt.last.Name {
56 t.Fatal("test setup does not collide under raw concatenation")
57 }
58 if tt.first.ID() == tt.last.ID() {
59 t.Fatalf("distinct keys have the same ID: %q", tt.first.ID())
60 }
61 })
62 }
63}
64
65func TestRemoteSessionKeyValidate(t *testing.T) {
66 tests := []struct {
67 name string
68 key RemoteSessionKey
69 wantErr bool
70 }{
71 {name: "valid", key: RemoteSessionKey{Host: "build@mule:2222/path", Name: "work.1"}},
72 {name: "empty host", key: RemoteSessionKey{Name: "work"}, wantErr: true},
73 {name: "host whitespace", key: RemoteSessionKey{Host: "build mule", Name: "work"}, wantErr: true},
74 {name: "empty session", key: RemoteSessionKey{Host: "arch"}, wantErr: true},
75 {name: "unsafe session", key: RemoteSessionKey{Host: "arch", Name: "work/session"}, wantErr: true},
76 }
77
78 for _, tt := range tests {
79 t.Run(tt.name, func(t *testing.T) {
80 err := tt.key.Validate()
81 if tt.wantErr && err == nil {
82 t.Fatal("RemoteSessionKey.Validate() = nil, want error")
83 }
84 if !tt.wantErr && err != nil {
85 t.Fatalf("RemoteSessionKey.Validate() = %v, want nil", err)
86 }
87 })
88 }
89}
90
91func TestRemoteSessionKeyDisplayIsPresentationOnly(t *testing.T) {
92 tests := []struct {
93 host string
94 displayOrigin string
95 want string
96 }{
97 {host: "arch", want: "hello@arch"},
98 {host: "route", displayOrigin: "user@arch", want: "hello@arch"},
99 {host: "test@arch", want: "hello@arch"},
100 {host: "test@arch:2222", want: "hello@arch:2222"},
101 {host: "test@[2001:db8::1]:2222", want: "hello@[2001:db8::1]:2222"},
102 {host: "test@", want: "hello@test@"},
103 {host: "@arch", want: "hello@arch"},
104 }
105 for _, test := range tests {
106 t.Run(test.host, func(t *testing.T) {
107 key := RemoteSessionKey{Host: test.host, Name: "hello", DisplayOrigin: test.displayOrigin}
108 if got := key.Display(); got != test.want {
109 t.Fatalf("RemoteSessionKey.Display() = %q, want %q", got, test.want)
110 }
111 if key.Host != test.host || key.Name != "hello" {
112 t.Fatalf("Display mutated routing key: %#v", key)
113 }
114 })
115 }
116}