ssh-hull 1.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +7 -0
- data/.github/workflows/ci.yml +44 -0
- data/.gitignore +27 -0
- data/.rubocop.yml +62 -0
- data/.tool-versions +1 -0
- data/Gemfile +5 -0
- data/Gemfile.lock +142 -0
- data/LICENSE +19 -0
- data/README.md +12 -0
- data/Rakefile +7 -0
- data/bin/bundle +114 -0
- data/bin/rake +29 -0
- data/bin/rspec +29 -0
- data/bin/rubocop +29 -0
- data/bomb +12 -0
- data/config/locales/en.yml +71 -0
- data/config/locales/fr.yml +71 -0
- data/exe/ssh-hull +12 -0
- data/exe/ssh-tunnel +1 -0
- data/lib/ssh-hull/cli.rb +113 -0
- data/lib/ssh-hull/logger.rb +6 -0
- data/lib/ssh-hull/ui/application.rb +47 -0
- data/lib/ssh-hull/ui/forms/application_form.rb +69 -0
- data/lib/ssh-hull/ui/forms/host_form.rb +27 -0
- data/lib/ssh-hull/ui/forms/tunnel_form.rb +31 -0
- data/lib/ssh-hull/ui/helpers/application_window_helper.rb +233 -0
- data/lib/ssh-hull/ui/helpers/common/form_helper.rb +169 -0
- data/lib/ssh-hull/ui/helpers/common/minimize_helper.rb +46 -0
- data/lib/ssh-hull/ui/helpers/common/modal_helper.rb +43 -0
- data/lib/ssh-hull/ui/helpers/common/toolbar_helper.rb +106 -0
- data/lib/ssh-hull/ui/helpers/common/translation_helper.rb +18 -0
- data/lib/ssh-hull/ui/helpers/common/tree_view_helper.rb +40 -0
- data/lib/ssh-hull/ui/helpers/host_window_helper.rb +230 -0
- data/lib/ssh-hull/ui/helpers/tunnel_window_helper.rb +96 -0
- data/lib/ssh-hull/ui/models/config.rb +82 -0
- data/lib/ssh-hull/ui/models/host.rb +90 -0
- data/lib/ssh-hull/ui/models/tunnel.rb +118 -0
- data/lib/ssh-hull/ui/status_icon.rb +45 -0
- data/lib/ssh-hull/ui/windows/about_window.rb +32 -0
- data/lib/ssh-hull/ui/windows/application_window.rb +42 -0
- data/lib/ssh-hull/ui/windows/hosts/delete_window.rb +56 -0
- data/lib/ssh-hull/ui/windows/hosts/edit_window.rb +39 -0
- data/lib/ssh-hull/ui/windows/hosts/new_window.rb +45 -0
- data/lib/ssh-hull/ui/windows/tunnels/delete_window.rb +57 -0
- data/lib/ssh-hull/ui/windows/tunnels/edit_window.rb +39 -0
- data/lib/ssh-hull/ui/windows/tunnels/new_window.rb +45 -0
- data/lib/ssh-hull/version.rb +17 -0
- data/lib/ssh-tunnel.rb +94 -0
- data/resources/gresources.xml +13 -0
- data/resources/ui/about_window.glade +48 -0
- data/resources/ui/application_window.glade +196 -0
- data/resources/ui/hosts/delete_window.glade +74 -0
- data/resources/ui/hosts/edit_window.glade +331 -0
- data/resources/ui/hosts/new_window.glade +328 -0
- data/resources/ui/tunnels/delete_window.glade +73 -0
- data/resources/ui/tunnels/edit_window.glade +305 -0
- data/resources/ui/tunnels/new_window.glade +305 -0
- data/snap/snapcraft.yaml +48 -0
- data/spec/factories/host.rb +22 -0
- data/spec/factories/tunnel.rb +16 -0
- data/spec/spec_helper.rb +31 -0
- data/spec/ssh_tunnel/ui/forms/host_form_spec.rb +103 -0
- data/spec/ssh_tunnel/ui/forms/tunnel_form_spec.rb +132 -0
- data/spec/ssh_tunnel/ui/models/host_spec.rb +116 -0
- data/spec/ssh_tunnel/ui/models/tunnel_spec.rb +43 -0
- data/spec/ssh_tunnel_spec.rb +45 -0
- data/ssh-hull.gemspec +38 -0
- metadata +320 -0
@@ -0,0 +1,305 @@
|
|
1
|
+
<?xml version="1.0" encoding="UTF-8"?>
|
2
|
+
<!-- Generated with glade 3.38.2 -->
|
3
|
+
<interface>
|
4
|
+
<requires lib="gtk+" version="3.18"/>
|
5
|
+
<template class="SSHTunnelUIWindowsTunnelsNewWindow" parent="GtkWindow">
|
6
|
+
<property name="visible">True</property>
|
7
|
+
<property name="can-focus">False</property>
|
8
|
+
<property name="has-focus">True</property>
|
9
|
+
<property name="is-focus">True</property>
|
10
|
+
<property name="type">popup</property>
|
11
|
+
<property name="modal">True</property>
|
12
|
+
<property name="window-position">center</property>
|
13
|
+
<property name="type-hint">dialog</property>
|
14
|
+
<property name="skip-taskbar-hint">True</property>
|
15
|
+
<property name="gravity">center</property>
|
16
|
+
<child>
|
17
|
+
<object class="GtkBox">
|
18
|
+
<property name="visible">True</property>
|
19
|
+
<property name="can-focus">False</property>
|
20
|
+
<property name="orientation">vertical</property>
|
21
|
+
<child>
|
22
|
+
<!-- n-columns=3 n-rows=7 -->
|
23
|
+
<object class="GtkGrid">
|
24
|
+
<property name="visible">True</property>
|
25
|
+
<property name="can-focus">False</property>
|
26
|
+
<child>
|
27
|
+
<object class="GtkLabel" id="label_name">
|
28
|
+
<property name="visible">True</property>
|
29
|
+
<property name="can-focus">False</property>
|
30
|
+
<property name="halign">start</property>
|
31
|
+
<property name="margin-start">10</property>
|
32
|
+
<property name="margin-end">5</property>
|
33
|
+
<property name="margin-top">10</property>
|
34
|
+
<property name="margin-bottom">5</property>
|
35
|
+
<property name="label" translatable="yes">Name</property>
|
36
|
+
</object>
|
37
|
+
<packing>
|
38
|
+
<property name="left-attach">0</property>
|
39
|
+
<property name="top-attach">0</property>
|
40
|
+
</packing>
|
41
|
+
</child>
|
42
|
+
<child>
|
43
|
+
<object class="GtkEntry" id="input_name">
|
44
|
+
<property name="visible">True</property>
|
45
|
+
<property name="can-focus">True</property>
|
46
|
+
<property name="margin-end">10</property>
|
47
|
+
<property name="margin-top">10</property>
|
48
|
+
<property name="margin-bottom">5</property>
|
49
|
+
<property name="hexpand">True</property>
|
50
|
+
</object>
|
51
|
+
<packing>
|
52
|
+
<property name="left-attach">1</property>
|
53
|
+
<property name="top-attach">0</property>
|
54
|
+
</packing>
|
55
|
+
</child>
|
56
|
+
<child>
|
57
|
+
<object class="GtkLabel" id="label_local_host">
|
58
|
+
<property name="visible">True</property>
|
59
|
+
<property name="can-focus">False</property>
|
60
|
+
<property name="halign">start</property>
|
61
|
+
<property name="margin-start">10</property>
|
62
|
+
<property name="margin-end">5</property>
|
63
|
+
<property name="margin-top">5</property>
|
64
|
+
<property name="margin-bottom">5</property>
|
65
|
+
<property name="label" translatable="yes">Local Host</property>
|
66
|
+
</object>
|
67
|
+
<packing>
|
68
|
+
<property name="left-attach">0</property>
|
69
|
+
<property name="top-attach">2</property>
|
70
|
+
</packing>
|
71
|
+
</child>
|
72
|
+
<child>
|
73
|
+
<object class="GtkLabel" id="label_local_port">
|
74
|
+
<property name="visible">True</property>
|
75
|
+
<property name="can-focus">False</property>
|
76
|
+
<property name="halign">start</property>
|
77
|
+
<property name="margin-start">10</property>
|
78
|
+
<property name="margin-end">5</property>
|
79
|
+
<property name="margin-top">5</property>
|
80
|
+
<property name="margin-bottom">5</property>
|
81
|
+
<property name="label" translatable="yes">Local Port</property>
|
82
|
+
</object>
|
83
|
+
<packing>
|
84
|
+
<property name="left-attach">0</property>
|
85
|
+
<property name="top-attach">3</property>
|
86
|
+
</packing>
|
87
|
+
</child>
|
88
|
+
<child>
|
89
|
+
<object class="GtkLabel" id="label_remote_host">
|
90
|
+
<property name="visible">True</property>
|
91
|
+
<property name="can-focus">False</property>
|
92
|
+
<property name="halign">start</property>
|
93
|
+
<property name="margin-start">10</property>
|
94
|
+
<property name="margin-end">5</property>
|
95
|
+
<property name="margin-top">5</property>
|
96
|
+
<property name="margin-bottom">5</property>
|
97
|
+
<property name="label" translatable="yes">Remote Host</property>
|
98
|
+
</object>
|
99
|
+
<packing>
|
100
|
+
<property name="left-attach">0</property>
|
101
|
+
<property name="top-attach">4</property>
|
102
|
+
</packing>
|
103
|
+
</child>
|
104
|
+
<child>
|
105
|
+
<object class="GtkLabel" id="label_remote_port">
|
106
|
+
<property name="visible">True</property>
|
107
|
+
<property name="can-focus">False</property>
|
108
|
+
<property name="halign">start</property>
|
109
|
+
<property name="margin-start">10</property>
|
110
|
+
<property name="margin-end">5</property>
|
111
|
+
<property name="margin-top">5</property>
|
112
|
+
<property name="margin-bottom">5</property>
|
113
|
+
<property name="label" translatable="yes">Remote Port</property>
|
114
|
+
</object>
|
115
|
+
<packing>
|
116
|
+
<property name="left-attach">0</property>
|
117
|
+
<property name="top-attach">5</property>
|
118
|
+
</packing>
|
119
|
+
</child>
|
120
|
+
<child>
|
121
|
+
<object class="GtkEntry" id="input_local_host">
|
122
|
+
<property name="visible">True</property>
|
123
|
+
<property name="can-focus">True</property>
|
124
|
+
<property name="margin-end">10</property>
|
125
|
+
<property name="margin-top">5</property>
|
126
|
+
<property name="margin-bottom">5</property>
|
127
|
+
<property name="hexpand">True</property>
|
128
|
+
</object>
|
129
|
+
<packing>
|
130
|
+
<property name="left-attach">1</property>
|
131
|
+
<property name="top-attach">2</property>
|
132
|
+
</packing>
|
133
|
+
</child>
|
134
|
+
<child>
|
135
|
+
<object class="GtkEntry" id="input_local_port">
|
136
|
+
<property name="visible">True</property>
|
137
|
+
<property name="can-focus">True</property>
|
138
|
+
<property name="margin-end">10</property>
|
139
|
+
<property name="margin-top">5</property>
|
140
|
+
<property name="margin-bottom">5</property>
|
141
|
+
<property name="hexpand">True</property>
|
142
|
+
</object>
|
143
|
+
<packing>
|
144
|
+
<property name="left-attach">1</property>
|
145
|
+
<property name="top-attach">3</property>
|
146
|
+
</packing>
|
147
|
+
</child>
|
148
|
+
<child>
|
149
|
+
<object class="GtkEntry" id="input_remote_host">
|
150
|
+
<property name="visible">True</property>
|
151
|
+
<property name="can-focus">True</property>
|
152
|
+
<property name="margin-end">10</property>
|
153
|
+
<property name="margin-top">5</property>
|
154
|
+
<property name="margin-bottom">5</property>
|
155
|
+
<property name="hexpand">True</property>
|
156
|
+
</object>
|
157
|
+
<packing>
|
158
|
+
<property name="left-attach">1</property>
|
159
|
+
<property name="top-attach">4</property>
|
160
|
+
</packing>
|
161
|
+
</child>
|
162
|
+
<child>
|
163
|
+
<object class="GtkEntry" id="input_remote_port">
|
164
|
+
<property name="visible">True</property>
|
165
|
+
<property name="can-focus">True</property>
|
166
|
+
<property name="margin-end">10</property>
|
167
|
+
<property name="margin-top">5</property>
|
168
|
+
<property name="margin-bottom">5</property>
|
169
|
+
<property name="hexpand">True</property>
|
170
|
+
</object>
|
171
|
+
<packing>
|
172
|
+
<property name="left-attach">1</property>
|
173
|
+
<property name="top-attach">5</property>
|
174
|
+
</packing>
|
175
|
+
</child>
|
176
|
+
<child>
|
177
|
+
<object class="GtkLabel" id="label_type">
|
178
|
+
<property name="visible">True</property>
|
179
|
+
<property name="can-focus">False</property>
|
180
|
+
<property name="halign">start</property>
|
181
|
+
<property name="margin-start">10</property>
|
182
|
+
<property name="margin-end">5</property>
|
183
|
+
<property name="margin-top">5</property>
|
184
|
+
<property name="margin-bottom">5</property>
|
185
|
+
<property name="label" translatable="yes">Type</property>
|
186
|
+
</object>
|
187
|
+
<packing>
|
188
|
+
<property name="left-attach">0</property>
|
189
|
+
<property name="top-attach">1</property>
|
190
|
+
</packing>
|
191
|
+
</child>
|
192
|
+
<child>
|
193
|
+
<object class="GtkComboBoxText" id="input_type">
|
194
|
+
<property name="visible">True</property>
|
195
|
+
<property name="can-focus">False</property>
|
196
|
+
<property name="margin-end">10</property>
|
197
|
+
<property name="margin-top">5</property>
|
198
|
+
<property name="margin-bottom">5</property>
|
199
|
+
</object>
|
200
|
+
<packing>
|
201
|
+
<property name="left-attach">1</property>
|
202
|
+
<property name="top-attach">1</property>
|
203
|
+
</packing>
|
204
|
+
</child>
|
205
|
+
<child>
|
206
|
+
<object class="GtkLabel" id="label_auto_start">
|
207
|
+
<property name="visible">True</property>
|
208
|
+
<property name="can-focus">False</property>
|
209
|
+
<property name="halign">start</property>
|
210
|
+
<property name="margin-left">10</property>
|
211
|
+
<property name="margin-right">5</property>
|
212
|
+
<property name="margin-start">10</property>
|
213
|
+
<property name="margin-end">5</property>
|
214
|
+
<property name="margin-top">5</property>
|
215
|
+
<property name="margin-bottom">10</property>
|
216
|
+
<property name="label" translatable="yes">Auto Start</property>
|
217
|
+
</object>
|
218
|
+
<packing>
|
219
|
+
<property name="left-attach">0</property>
|
220
|
+
<property name="top-attach">6</property>
|
221
|
+
</packing>
|
222
|
+
</child>
|
223
|
+
<child>
|
224
|
+
<object class="GtkCheckButton" id="input_auto_start">
|
225
|
+
<property name="visible">True</property>
|
226
|
+
<property name="can-focus">True</property>
|
227
|
+
<property name="receives-default">False</property>
|
228
|
+
<property name="margin-top">5</property>
|
229
|
+
<property name="margin-bottom">10</property>
|
230
|
+
<property name="draw-indicator">True</property>
|
231
|
+
</object>
|
232
|
+
<packing>
|
233
|
+
<property name="left-attach">1</property>
|
234
|
+
<property name="top-attach">6</property>
|
235
|
+
</packing>
|
236
|
+
</child>
|
237
|
+
<child>
|
238
|
+
<placeholder/>
|
239
|
+
</child>
|
240
|
+
<child>
|
241
|
+
<placeholder/>
|
242
|
+
</child>
|
243
|
+
<child>
|
244
|
+
<placeholder/>
|
245
|
+
</child>
|
246
|
+
<child>
|
247
|
+
<placeholder/>
|
248
|
+
</child>
|
249
|
+
<child>
|
250
|
+
<placeholder/>
|
251
|
+
</child>
|
252
|
+
<child>
|
253
|
+
<placeholder/>
|
254
|
+
</child>
|
255
|
+
<child>
|
256
|
+
<placeholder/>
|
257
|
+
</child>
|
258
|
+
</object>
|
259
|
+
<packing>
|
260
|
+
<property name="expand">True</property>
|
261
|
+
<property name="fill">True</property>
|
262
|
+
<property name="position">0</property>
|
263
|
+
</packing>
|
264
|
+
</child>
|
265
|
+
<child>
|
266
|
+
<object class="GtkActionBar">
|
267
|
+
<property name="visible">True</property>
|
268
|
+
<property name="can-focus">False</property>
|
269
|
+
<child>
|
270
|
+
<object class="GtkButton" id="button_cancel">
|
271
|
+
<property name="label">gtk-cancel</property>
|
272
|
+
<property name="visible">True</property>
|
273
|
+
<property name="can-focus">True</property>
|
274
|
+
<property name="receives-default">True</property>
|
275
|
+
<property name="use-stock">True</property>
|
276
|
+
</object>
|
277
|
+
<packing>
|
278
|
+
<property name="pack-type">end</property>
|
279
|
+
<property name="position">0</property>
|
280
|
+
</packing>
|
281
|
+
</child>
|
282
|
+
<child>
|
283
|
+
<object class="GtkButton" id="button_submit">
|
284
|
+
<property name="label">gtk-apply</property>
|
285
|
+
<property name="visible">True</property>
|
286
|
+
<property name="can-focus">True</property>
|
287
|
+
<property name="receives-default">True</property>
|
288
|
+
<property name="use-stock">True</property>
|
289
|
+
</object>
|
290
|
+
<packing>
|
291
|
+
<property name="pack-type">end</property>
|
292
|
+
<property name="position">0</property>
|
293
|
+
</packing>
|
294
|
+
</child>
|
295
|
+
</object>
|
296
|
+
<packing>
|
297
|
+
<property name="expand">False</property>
|
298
|
+
<property name="fill">True</property>
|
299
|
+
<property name="position">1</property>
|
300
|
+
</packing>
|
301
|
+
</child>
|
302
|
+
</object>
|
303
|
+
</child>
|
304
|
+
</template>
|
305
|
+
</interface>
|
data/snap/snapcraft.yaml
ADDED
@@ -0,0 +1,48 @@
|
|
1
|
+
name: ssh-hull
|
2
|
+
version: '1.0.0'
|
3
|
+
grade: devel
|
4
|
+
confinement: devmode
|
5
|
+
summary: SSH Tunnel Manager
|
6
|
+
description: |
|
7
|
+
A Ruby/GTK3 application to manage ssh hulls.
|
8
|
+
|
9
|
+
apps:
|
10
|
+
ssh-hull:
|
11
|
+
command: desktop-launch $SNAP/bin/ssh-hull
|
12
|
+
plugs:
|
13
|
+
- home
|
14
|
+
- desktop
|
15
|
+
- desktop-legacy
|
16
|
+
- network
|
17
|
+
- x11
|
18
|
+
|
19
|
+
parts:
|
20
|
+
ssh-hull:
|
21
|
+
source: https://github.com/ungtb10d/ssh-hull.git
|
22
|
+
source-type: git
|
23
|
+
plugin: ruby
|
24
|
+
ruby-version: 2.5.5
|
25
|
+
after:
|
26
|
+
- desktop-gtk3
|
27
|
+
build-packages:
|
28
|
+
- build-essential
|
29
|
+
- libatk1.0-dev
|
30
|
+
- libgirepository1.0-dev
|
31
|
+
- libpango1.0-dev
|
32
|
+
- libgtk-3-dev
|
33
|
+
stage-packages:
|
34
|
+
- gobject-introspection
|
35
|
+
- gir1.2-atk-1.0
|
36
|
+
- gir1.2-atspi-2.0
|
37
|
+
- gir1.2-freedesktop
|
38
|
+
- gir1.2-gdkpixbuf-2.0
|
39
|
+
- gir1.2-glib-2.0
|
40
|
+
- gir1.2-gtk-3.0
|
41
|
+
- gir1.2-pango-1.0
|
42
|
+
- adwaita-icon-theme
|
43
|
+
- libcanberra-gtk3-0
|
44
|
+
override-build: |
|
45
|
+
snapcraftctl build
|
46
|
+
git checkout snap/snapcraft.yaml
|
47
|
+
gem build ssh-hull.gemspec
|
48
|
+
gem install ssh-hull-*.gem --env-shebang
|
@@ -0,0 +1,22 @@
|
|
1
|
+
FactoryBot.define do
|
2
|
+
factory :host, class: 'SSHTunnel::UI::Models::Host' do
|
3
|
+
|
4
|
+
uuid { '7be48819-97bf-49fc-98af-4f7f096e1977' }
|
5
|
+
name { 'foo' }
|
6
|
+
user { 'root' }
|
7
|
+
host { 'host.example.net' }
|
8
|
+
port { 22 }
|
9
|
+
|
10
|
+
factory :host_with_one_tunnel do
|
11
|
+
after(:build) do |object, _evaluator|
|
12
|
+
object.tunnels = [build(:tunnel, parent: object)]
|
13
|
+
end
|
14
|
+
end
|
15
|
+
|
16
|
+
factory :host_with_two_tunnels do
|
17
|
+
after(:build) do |object, _evaluator|
|
18
|
+
object.tunnels = [build(:tunnel, name: 'zzz', parent: object), build(:tunnel, name: 'aaa', parent: object)]
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
@@ -0,0 +1,16 @@
|
|
1
|
+
FactoryBot.define do
|
2
|
+
factory :tunnel, class: 'SSHTunnel::UI::Models::Tunnel' do
|
3
|
+
|
4
|
+
uuid { '117aacde-5adf-4a6d-a0f9-5acdddf4a5b9' }
|
5
|
+
name { 'mysql' }
|
6
|
+
type { 'local' }
|
7
|
+
local_host { '127.0.0.1' }
|
8
|
+
local_port { 10000 }
|
9
|
+
remote_host { '127.0.0.1' }
|
10
|
+
remote_port { 3306 }
|
11
|
+
|
12
|
+
factory :tunnel_wih_parent do
|
13
|
+
parent { build(:host) }
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|
data/spec/spec_helper.rb
ADDED
@@ -0,0 +1,31 @@
|
|
1
|
+
require 'simplecov'
|
2
|
+
require 'rspec'
|
3
|
+
require 'factory_bot'
|
4
|
+
|
5
|
+
# Start Simplecov
|
6
|
+
SimpleCov.start do
|
7
|
+
add_filter 'spec/'
|
8
|
+
end
|
9
|
+
|
10
|
+
# Configure RSpec
|
11
|
+
RSpec.configure do |config|
|
12
|
+
config.color = true
|
13
|
+
config.fail_fast = false
|
14
|
+
|
15
|
+
config.order = :random
|
16
|
+
Kernel.srand config.seed
|
17
|
+
|
18
|
+
config.expect_with :rspec do |c|
|
19
|
+
c.syntax = :expect
|
20
|
+
end
|
21
|
+
|
22
|
+
# disable monkey patching
|
23
|
+
# see: https://relishapp.com/rspec/rspec-core/v/3-8/docs/configuration/zero-monkey-patching-mode
|
24
|
+
config.disable_monkey_patching!
|
25
|
+
|
26
|
+
config.before(:suite) do
|
27
|
+
FactoryBot.find_definitions
|
28
|
+
end
|
29
|
+
end
|
30
|
+
|
31
|
+
require 'ssh-hull'
|
@@ -0,0 +1,103 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
RSpec.describe SSHTunnel::UI::Forms::HostForm do
|
4
|
+
|
5
|
+
let(:host) { FactoryBot.build(:host) }
|
6
|
+
let(:form) { described_class.new(host) }
|
7
|
+
let(:params) { { name: 'My Host', user: 'root', host: 'foo.bar', port: 22 } }
|
8
|
+
|
9
|
+
describe 'form' do
|
10
|
+
it 'has attributes' do
|
11
|
+
expect(form.name).to be nil
|
12
|
+
expect(form.user).to be nil
|
13
|
+
expect(form.host).to be nil
|
14
|
+
expect(form.port).to be nil
|
15
|
+
end
|
16
|
+
end
|
17
|
+
|
18
|
+
describe '#submit' do
|
19
|
+
it 'assigns attributes value' do
|
20
|
+
form.submit(params)
|
21
|
+
expect(form.name).to eq 'My Host'
|
22
|
+
expect(form.user).to eq 'root'
|
23
|
+
expect(form.host).to eq 'foo.bar'
|
24
|
+
expect(form.port).to eq 22
|
25
|
+
end
|
26
|
+
end
|
27
|
+
|
28
|
+
describe '#valid?' do
|
29
|
+
context 'with valid params' do
|
30
|
+
it 'returns true' do
|
31
|
+
form.submit(params)
|
32
|
+
expect(form.valid?).to be true
|
33
|
+
end
|
34
|
+
end
|
35
|
+
|
36
|
+
context 'with invalid params' do
|
37
|
+
let(:params) { {} }
|
38
|
+
|
39
|
+
it 'returns false' do
|
40
|
+
form.submit(params)
|
41
|
+
expect(form.valid?).to be false
|
42
|
+
end
|
43
|
+
end
|
44
|
+
end
|
45
|
+
|
46
|
+
describe '#save' do
|
47
|
+
it 'should save value on model' do
|
48
|
+
expect(host.uuid).to eq '7be48819-97bf-49fc-98af-4f7f096e1977'
|
49
|
+
expect(host.name).to eq 'foo'
|
50
|
+
expect(host.user).to eq 'root'
|
51
|
+
expect(host.host).to eq 'host.example.net'
|
52
|
+
expect(host.port).to eq "22"
|
53
|
+
|
54
|
+
form.submit(params)
|
55
|
+
form.save
|
56
|
+
|
57
|
+
expect(host.uuid).to eq '7be48819-97bf-49fc-98af-4f7f096e1977'
|
58
|
+
expect(host.name).to eq 'My Host'
|
59
|
+
expect(host.user).to eq 'root'
|
60
|
+
expect(host.host).to eq 'foo.bar'
|
61
|
+
expect(host.port).to eq "22"
|
62
|
+
end
|
63
|
+
end
|
64
|
+
|
65
|
+
describe 'valid form' do
|
66
|
+
it 'should cast port to Integer' do
|
67
|
+
params = { name: 'My Host', user: 'root', host: 'foo.bar', port: '22' }
|
68
|
+
form.submit(params)
|
69
|
+
expect(form.valid?).to be true
|
70
|
+
expect(form.port).to eq 22
|
71
|
+
end
|
72
|
+
end
|
73
|
+
|
74
|
+
describe 'invalid form' do
|
75
|
+
it 'should have a name' do
|
76
|
+
params = { name: '', user: 'root', host: 'foo.bar', port: 22 }
|
77
|
+
form.submit(params)
|
78
|
+
expect(form.valid?).to be false
|
79
|
+
expect(form.errors.messages_for(:name)).to eq ["can't be blank"]
|
80
|
+
end
|
81
|
+
|
82
|
+
it 'should have a user' do
|
83
|
+
params = { name: 'My Host', user: '', host: 'foo.bar', port: 22 }
|
84
|
+
form.submit(params)
|
85
|
+
expect(form.valid?).to be false
|
86
|
+
expect(form.errors.messages_for(:user)).to eq ["can't be blank"]
|
87
|
+
end
|
88
|
+
|
89
|
+
it 'should have a host' do
|
90
|
+
params = { name: 'My Host', user: 'root', host: '', port: 22 }
|
91
|
+
form.submit(params)
|
92
|
+
expect(form.valid?).to be false
|
93
|
+
expect(form.errors.messages_for(:host)).to eq ["can't be blank"]
|
94
|
+
end
|
95
|
+
|
96
|
+
it 'should have a port' do
|
97
|
+
params = { name: 'My Host', user: 'root', host: 'foo.bar', port: '' }
|
98
|
+
form.submit(params)
|
99
|
+
expect(form.valid?).to be false
|
100
|
+
expect(form.errors.messages_for(:port)).to eq ["can't be blank", "is not included in the list"]
|
101
|
+
end
|
102
|
+
end
|
103
|
+
end
|
@@ -0,0 +1,132 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
RSpec.describe SSHTunnel::UI::Forms::TunnelForm do
|
4
|
+
|
5
|
+
let(:tunnel) { FactoryBot.build(:tunnel_wih_parent) }
|
6
|
+
let(:form) { described_class.new(tunnel) }
|
7
|
+
let(:params) { { name: 'My Tunnel', type: 'remote', local_host: '127.0.0.1', local_port: 5000, remote_host: '127.0.0.1', remote_port: 6379 } }
|
8
|
+
|
9
|
+
describe 'form' do
|
10
|
+
it 'has attributes' do
|
11
|
+
expect(form.name).to be nil
|
12
|
+
expect(form.type).to be nil
|
13
|
+
expect(form.local_host).to be nil
|
14
|
+
expect(form.local_port).to be nil
|
15
|
+
expect(form.remote_host).to be nil
|
16
|
+
expect(form.remote_port).to be nil
|
17
|
+
end
|
18
|
+
end
|
19
|
+
|
20
|
+
describe '#submit' do
|
21
|
+
it 'assigns attributes value' do
|
22
|
+
form.submit(params)
|
23
|
+
expect(form.name).to eq 'My Tunnel'
|
24
|
+
expect(form.type).to eq 'remote'
|
25
|
+
expect(form.local_host).to eq '127.0.0.1'
|
26
|
+
expect(form.local_port).to eq 5000
|
27
|
+
expect(form.remote_host).to eq '127.0.0.1'
|
28
|
+
expect(form.remote_port).to eq 6379
|
29
|
+
end
|
30
|
+
end
|
31
|
+
|
32
|
+
describe '#valid?' do
|
33
|
+
context 'with valid params' do
|
34
|
+
it 'returns true' do
|
35
|
+
form.submit(params)
|
36
|
+
expect(form.valid?).to be true
|
37
|
+
end
|
38
|
+
end
|
39
|
+
|
40
|
+
context 'with invalid params' do
|
41
|
+
let(:params) { {} }
|
42
|
+
|
43
|
+
it 'returns false' do
|
44
|
+
form.submit(params)
|
45
|
+
expect(form.valid?).to be false
|
46
|
+
end
|
47
|
+
end
|
48
|
+
end
|
49
|
+
|
50
|
+
describe '#save' do
|
51
|
+
it 'should save value on model' do
|
52
|
+
expect(tunnel.uuid).to eq '117aacde-5adf-4a6d-a0f9-5acdddf4a5b9'
|
53
|
+
expect(tunnel.name).to eq 'mysql'
|
54
|
+
expect(tunnel.type).to eq 'local'
|
55
|
+
expect(tunnel.local_host).to eq '127.0.0.1'
|
56
|
+
expect(tunnel.local_port).to eq "10000"
|
57
|
+
expect(tunnel.remote_host).to eq '127.0.0.1'
|
58
|
+
expect(tunnel.remote_port).to eq "3306"
|
59
|
+
|
60
|
+
form.submit(params)
|
61
|
+
form.save
|
62
|
+
|
63
|
+
expect(tunnel.uuid).to eq '117aacde-5adf-4a6d-a0f9-5acdddf4a5b9'
|
64
|
+
expect(tunnel.name).to eq 'My Tunnel'
|
65
|
+
expect(tunnel.type).to eq 'remote'
|
66
|
+
expect(tunnel.local_host).to eq '127.0.0.1'
|
67
|
+
expect(tunnel.local_port).to eq "5000"
|
68
|
+
expect(tunnel.remote_host).to eq '127.0.0.1'
|
69
|
+
expect(tunnel.remote_port).to eq "6379"
|
70
|
+
end
|
71
|
+
end
|
72
|
+
|
73
|
+
describe 'valid form' do
|
74
|
+
it 'should cast local_port to Integer' do
|
75
|
+
params = { name: 'My Tunnel', type: 'local', local_host: '127.0.0.1', local_port: '5000', remote_host: '127.0.0.1', remote_port: 3306 }
|
76
|
+
form.submit(params)
|
77
|
+
expect(form.valid?).to be true
|
78
|
+
expect(form.local_port).to eq 5000
|
79
|
+
end
|
80
|
+
|
81
|
+
it 'should cast remote_port to Integer' do
|
82
|
+
params = { name: 'My Tunnel', type: 'local', local_host: '127.0.0.1', local_port: 5000, remote_host: '127.0.0.1', remote_port: '3306' }
|
83
|
+
form.submit(params)
|
84
|
+
expect(form.valid?).to be true
|
85
|
+
expect(form.remote_port).to eq 3306
|
86
|
+
end
|
87
|
+
end
|
88
|
+
|
89
|
+
describe 'invalid form' do
|
90
|
+
it 'should have a name' do
|
91
|
+
params = { name: '', type: 'local', local_host: '127.0.0.1', local_port: 5000, remote_host: '127.0.0.1', remote_port: 3306 }
|
92
|
+
form.submit(params)
|
93
|
+
expect(form.valid?).to be false
|
94
|
+
expect(form.errors.messages_for(:name)).to eq ["can't be blank"]
|
95
|
+
end
|
96
|
+
|
97
|
+
it 'should have a type' do
|
98
|
+
params = { name: 'My Tunnel', type: '', local_host: '127.0.0.1', local_port: 5000, remote_host: '127.0.0.1', remote_port: 3306 }
|
99
|
+
form.submit(params)
|
100
|
+
expect(form.valid?).to be false
|
101
|
+
expect(form.errors.messages_for(:type)).to eq ["can't be blank"]
|
102
|
+
end
|
103
|
+
|
104
|
+
it 'should have a local_host' do
|
105
|
+
params = { name: 'My Tunnel', type: 'local', local_host: '', local_port: 5000, remote_host: '127.0.0.1', remote_port: 3306 }
|
106
|
+
form.submit(params)
|
107
|
+
expect(form.valid?).to be false
|
108
|
+
expect(form.errors.messages_for(:local_host)).to eq ["can't be blank"]
|
109
|
+
end
|
110
|
+
|
111
|
+
it 'should have a local_port' do
|
112
|
+
params = { name: 'My Tunnel', type: 'local', local_host: '127.0.0.1', local_port: '', remote_host: '127.0.0.1', remote_port: 3306 }
|
113
|
+
form.submit(params)
|
114
|
+
expect(form.valid?).to be false
|
115
|
+
expect(form.errors.messages_for(:local_port)).to eq ["can't be blank", "is not included in the list"]
|
116
|
+
end
|
117
|
+
|
118
|
+
it 'should have a remote_host' do
|
119
|
+
params = { name: 'My Tunnel', type: 'local', local_host: '127.0.0.1', local_port: 5000, remote_host: '', remote_port: 3306 }
|
120
|
+
form.submit(params)
|
121
|
+
expect(form.valid?).to be false
|
122
|
+
expect(form.errors.messages_for(:remote_host)).to eq ["can't be blank"]
|
123
|
+
end
|
124
|
+
|
125
|
+
it 'should have a remote_port' do
|
126
|
+
params = { name: 'My Tunnel', type: 'local', local_host: '127.0.0.1', local_port: 5000, remote_host: '127.0.0.1', remote_port: '' }
|
127
|
+
form.submit(params)
|
128
|
+
expect(form.valid?).to be false
|
129
|
+
expect(form.errors.messages_for(:remote_port)).to eq ["can't be blank", "is not included in the list"]
|
130
|
+
end
|
131
|
+
end
|
132
|
+
end
|