roku_builder 3.3.2

Sign up to get free protection for your applications and to get access to all the features.
Files changed (46) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +4 -0
  3. data/Gemfile +4 -0
  4. data/Gemfile.lock +101 -0
  5. data/Guardfile +21 -0
  6. data/LICENSE.txt +22 -0
  7. data/README.md +282 -0
  8. data/bin/roku +152 -0
  9. data/config.json.example +28 -0
  10. data/lib/roku_builder.rb +32 -0
  11. data/lib/roku_builder/config_manager.rb +157 -0
  12. data/lib/roku_builder/controller.rb +582 -0
  13. data/lib/roku_builder/inspector.rb +90 -0
  14. data/lib/roku_builder/keyer.rb +52 -0
  15. data/lib/roku_builder/linker.rb +46 -0
  16. data/lib/roku_builder/loader.rb +197 -0
  17. data/lib/roku_builder/manifest_manager.rb +63 -0
  18. data/lib/roku_builder/monitor.rb +62 -0
  19. data/lib/roku_builder/navigator.rb +107 -0
  20. data/lib/roku_builder/packager.rb +47 -0
  21. data/lib/roku_builder/tester.rb +32 -0
  22. data/lib/roku_builder/util.rb +31 -0
  23. data/lib/roku_builder/version.rb +4 -0
  24. data/rakefile +8 -0
  25. data/roku_builder.gemspec +36 -0
  26. data/tests/roku_builder/config_manager_test.rb +400 -0
  27. data/tests/roku_builder/controller_test.rb +250 -0
  28. data/tests/roku_builder/inspector_test.rb +153 -0
  29. data/tests/roku_builder/keyer_test.rb +88 -0
  30. data/tests/roku_builder/linker_test.rb +37 -0
  31. data/tests/roku_builder/loader_test.rb +153 -0
  32. data/tests/roku_builder/manifest_manager_test.rb +25 -0
  33. data/tests/roku_builder/monitor_test.rb +34 -0
  34. data/tests/roku_builder/navigator_test.rb +72 -0
  35. data/tests/roku_builder/packager_test.rb +125 -0
  36. data/tests/roku_builder/test_files/controller_test/load_config_test.json +28 -0
  37. data/tests/roku_builder/test_files/controller_test/valid_config.json +28 -0
  38. data/tests/roku_builder/test_files/loader_test/c +0 -0
  39. data/tests/roku_builder/test_files/loader_test/manifest +0 -0
  40. data/tests/roku_builder/test_files/loader_test/source/a +0 -0
  41. data/tests/roku_builder/test_files/loader_test/source/b +0 -0
  42. data/tests/roku_builder/test_files/manifest_manager_test/manifest_template +2 -0
  43. data/tests/roku_builder/test_helper.rb +6 -0
  44. data/tests/roku_builder/tester_test.rb +33 -0
  45. data/tests/roku_builder/util_test.rb +23 -0
  46. metadata +286 -0
@@ -0,0 +1,62 @@
1
+ module RokuBuilder
2
+
3
+ # Monitor development Logs
4
+ class Monitor < Util
5
+
6
+ # Initialize port config
7
+ def init()
8
+ @ports = {
9
+ main: 8085,
10
+ sg: 8089,
11
+ task1: 8090,
12
+ task2: 8091,
13
+ task3: 8092,
14
+ taskX: 8093,
15
+ }
16
+ end
17
+
18
+ # Monitor a development log on the Roku device
19
+ # @param type [Symbol] The log type to monitor
20
+ # @param verbose [Boolean] Print status messages.
21
+ def monitor(type:)
22
+ telnet_config = {
23
+ 'Host' => @roku_ip_address,
24
+ 'Port' => @ports[type]
25
+ }
26
+ waitfor_config = {
27
+ 'Match' => /./,
28
+ 'Timeout' => false
29
+ }
30
+
31
+ thread = Thread.new(telnet_config, waitfor_config) {|telnet_config,waitfor_config|
32
+ @logger.info "Monitoring #{type} console(#{telnet_config['Port']}) on #{telnet_config['Host'] }"
33
+ connection = Net::Telnet.new(telnet_config)
34
+ Thread.current[:connection] = connection
35
+ all_text = ""
36
+ while true
37
+ connection.waitfor(waitfor_config) do |txt|
38
+ all_text += txt
39
+ while line = all_text.slice!(/^.*\n/) do
40
+ puts line
41
+ end
42
+ if all_text == "BrightScript Debugger> "
43
+ print all_text
44
+ all_text = ""
45
+ end
46
+ end
47
+ end
48
+ }
49
+ running = true
50
+ while running
51
+ @logger.info "Q to exit"
52
+ command = gets.chomp
53
+ if command == "q"
54
+ thread.exit
55
+ running = false
56
+ else
57
+ thread[:connection].puts(command)
58
+ end
59
+ end
60
+ end
61
+ end
62
+ end
@@ -0,0 +1,107 @@
1
+ module RokuBuilder
2
+
3
+ # Navigation methods
4
+ class Navigator < Util
5
+
6
+ # Setup navigation commands
7
+ def init
8
+ @commands = {
9
+ up: "Up",
10
+ down: "Down",
11
+ right: "Right",
12
+ left: "Left",
13
+ select: "Select",
14
+ back: "Back",
15
+ home: "Home",
16
+ rew: "Rev",
17
+ ff: "Fwd",
18
+ play: "Play",
19
+ replay: "InstantReplay"
20
+ }
21
+
22
+ @screens = {
23
+ platform: [:home, :home, :home, :home, :home, :ff, :play, :rew, :play, :ff],
24
+ secret: [:home, :home, :home, :home, :home, :ff, :ff, :ff, :rew, :rew],
25
+ secret2: [:home, :home, :home, :home, :home, :up, :right, :down, :left, :up],
26
+ channels: [:home, :home, :home, :up, :up, :left, :right, :left, :right, :left],
27
+ developer: [:home, :home, :home, :up, :up, :right, :left, :right, :left, :right],
28
+ wifi: [:home, :home, :home, :home, :home, :up, :down, :up, :down, :up],
29
+ antenna: [:home, :home, :home, :home, :home, :ff, :down, :rew, :down, :ff],
30
+ bitrate: [:home, :home, :home, :home, :home, :rew, :rew, :rew, :ff, :ff],
31
+ network: [:home, :home, :home, :home, :home, :right, :left, :right, :left, :right],
32
+ reboot: [:home, :home, :home, :home, :home, :up, :rew, :rew, :ff, :ff]
33
+ }
34
+ end
35
+
36
+ # Send a navigation command to the roku device
37
+ # @param command [Symbol] The smbol of the command to send
38
+ # @return [Boolean] Success
39
+ def nav(command:)
40
+ if @commands.has_key?(command)
41
+ conn = Faraday.new(url: "#{@url}:8060") do |f|
42
+ f.request :multipart
43
+ f.request :url_encoded
44
+ f.adapter Faraday.default_adapter
45
+ end
46
+
47
+ path = "/keypress/#{@commands[command]}"
48
+ response = conn.post path
49
+ return response.success?
50
+ else
51
+ return false
52
+ end
53
+ end
54
+
55
+ # Type text on the roku device
56
+ # @param text [String] The text to type on the device
57
+ # @return [Boolean] Success
58
+ def type(text:)
59
+ conn = Faraday.new(url: "#{@url}:8060") do |f|
60
+ f.request :multipart
61
+ f.request :url_encoded
62
+ f.adapter Faraday.default_adapter
63
+ end
64
+ text.split(//).each do |c|
65
+ path = "/keypress/LIT_#{CGI::escape(c)}"
66
+ response = conn.post path
67
+ return false unless response.success?
68
+ end
69
+ return true
70
+ end
71
+
72
+ # Show the commands for one of the roku secret screens
73
+ # @param type [Symbol] The type of screen to show
74
+ # @return [Boolean] Screen found
75
+ def screen(type:)
76
+ if @screens.has_key?(type)
77
+ display = []
78
+ count = []
79
+ @screens[type].each do |command|
80
+ if display.count > 0 and display[-1] == command
81
+ count[-1] = count[-1] + 1
82
+ else
83
+ display.push(command)
84
+ count.push(1)
85
+ end
86
+ end
87
+ string = ""
88
+ display.each_index do |i|
89
+ if count[i] > 1
90
+ string = string + @commands[display[i]]+" x "+count[i].to_s+", "
91
+ else
92
+ string = string + @commands[display[i]]+", "
93
+ end
94
+ end
95
+ @logger.unknown(string.strip)
96
+ else
97
+ return false
98
+ end
99
+ true
100
+ end
101
+
102
+ # Show avaiable roku secret screens
103
+ def screens
104
+ @screens.keys.each {|screen| @logger.unknown(screen)}
105
+ end
106
+ end
107
+ end
@@ -0,0 +1,47 @@
1
+ module RokuBuilder
2
+
3
+ # Method of packaging app for submission
4
+ class Packager < Util
5
+
6
+ # Sign and download the currently sideloaded app
7
+ # @param app_name_version [String] The name and version of the package
8
+ # @param out_file [String] Location to download signed package to
9
+ # @param password [String] Password for the devices current key
10
+ # @return [Boolean] True on package success and download, false otherwise
11
+ def package(app_name_version:, out_file:, password:)
12
+ # Sign package
13
+ path = "/plugin_package"
14
+ conn = Faraday.new(url: @url) do |f|
15
+ f.headers['Content-Type'] = Faraday::Request::Multipart.mime_type
16
+ f.request :digest, @dev_username, @dev_password
17
+ f.request :multipart
18
+ f.request :url_encoded
19
+ f.adapter Faraday.default_adapter
20
+ end
21
+ payload = {
22
+ mysubmit: "Package",
23
+ app_name: app_name_version,
24
+ passwd: password,
25
+ pkg_time: Time.now.to_i
26
+ }
27
+ response = conn.post path, payload
28
+
29
+ # Check for error
30
+ failed = /(Failed: [^\.]*\.)/.match(response.body)
31
+ return failed[1] if failed
32
+
33
+ # Download signed package
34
+ pkg = /<a href="pkgs[^>]*>([^<]*)</.match(response.body)[1]
35
+ path = "/pkgs/#{pkg}"
36
+ conn = Faraday.new(url: @url) do |f|
37
+ f.request :digest, @dev_username, @dev_password
38
+ f.adapter Faraday.default_adapter
39
+ end
40
+ response = conn.get path
41
+ return false if response.status != 200
42
+
43
+ File.open(out_file, 'w+') {|fp| fp.write(response.body)}
44
+ true
45
+ end
46
+ end
47
+ end
@@ -0,0 +1,32 @@
1
+ module RokuBuilder
2
+
3
+ # Method for running unit tests
4
+ # This is intended to be used with the brstest librbary but should work
5
+ # with other testing libraries
6
+ class Tester < Util
7
+
8
+ # Run tests and report results
9
+ # @param sideload_config [Hash] The config for sideloading the app
10
+ def run_tests(sideload_config:)
11
+ telnet_config ={
12
+ 'Host' => @roku_ip_address,
13
+ 'Port' => 8085
14
+ }
15
+
16
+ loader = Loader.new(**@device_config)
17
+ connection = Net::Telnet.new(telnet_config)
18
+ loader.sideload(**sideload_config)
19
+
20
+ in_tests = false
21
+ end_reg = /\*\*\*\*\* ENDING TESTS \*\*\*\*\*/
22
+ connection.waitfor(end_reg) do |txt|
23
+ txt.split("\n").each do |line|
24
+ in_tests = false if line =~ end_reg
25
+ @logger.unknown line if in_tests
26
+ in_tests = true if line =~ /\*\*\*\*\* STARTING TESTS \*\*\*\*\*/
27
+ end
28
+ end
29
+ connection.puts("cont\n")
30
+ end
31
+ end
32
+ end
@@ -0,0 +1,31 @@
1
+ module RokuBuilder
2
+
3
+ # Super class for device utilities
4
+ # This class defines a common initializer and allows subclasses
5
+ # to define their own secondary initializer
6
+ class Util
7
+
8
+ # Common initializer of device utils
9
+ # @param ip [String] IP address of roku device
10
+ # @param user [String] Username for roku device
11
+ # @param password [String] Password for roku device
12
+ def initialize(ip:, user:, password:, logger:)
13
+ @device_config = {
14
+ ip: ip,
15
+ user: user,
16
+ password: password
17
+ }
18
+ @roku_ip_address = ip
19
+ @dev_username = user
20
+ @dev_password = password
21
+ @url = "http://#{@roku_ip_address}"
22
+ @logger = logger
23
+ init()
24
+ end
25
+
26
+ # Second initializer to be overwriten
27
+ def init
28
+ #Override in subclass
29
+ end
30
+ end
31
+ end
@@ -0,0 +1,4 @@
1
+ module RokuBuilder
2
+ # Version of the RokuBuilder Gem
3
+ VERSION = "3.3.2"
4
+ end
data/rakefile ADDED
@@ -0,0 +1,8 @@
1
+ require 'rake'
2
+ require 'rake/testtask'
3
+
4
+ Rake::TestTask.new do |t|
5
+ t.test_files = Dir.glob('tests/roku_builder/*_test.rb')
6
+ end
7
+
8
+ task(default: :test)
@@ -0,0 +1,36 @@
1
+ # coding: utf-8
2
+ lib = File.expand_path('../lib', __FILE__)
3
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
+ require 'roku_builder/version'
5
+
6
+ Gem::Specification.new do |spec|
7
+ spec.name = "roku_builder"
8
+ spec.version = RokuBuilder::VERSION
9
+ spec.authors = ["greeneca"]
10
+ spec.email = ["charles.greene@redspace.com"]
11
+ spec.summary = %q{Build Tool for Roku Apps}
12
+ spec.description = %q{Allows the user to easily sideload, package, deeplink, test, roku apps.}
13
+ spec.homepage = ""
14
+ spec.license = "MIT"
15
+
16
+ spec.files = `git ls-files -z`.split("\x0")
17
+ spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
18
+ spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
19
+ spec.require_paths = ["lib"]
20
+
21
+ spec.add_dependency "rubyzip", "~> 1.1"
22
+ spec.add_dependency "faraday", "~> 0.9"
23
+ spec.add_dependency "faraday-digestauth", "~> 0.2"
24
+ spec.add_dependency "git", "~> 1.2.9"
25
+ spec.add_dependency "net-ping", "~> 1.7"
26
+
27
+ spec.add_development_dependency "bundler", "~> 1.7"
28
+ spec.add_development_dependency "rake", "~> 10.0"
29
+ spec.add_development_dependency "byebug", "~> 3.5"
30
+ spec.add_development_dependency "minitest", "~> 5.8"
31
+ spec.add_development_dependency "minitest-autotest", "~> 1.0"
32
+ spec.add_development_dependency "minitest-server", "~> 1.0"
33
+ spec.add_development_dependency "simplecov", "~> 0.11"
34
+ spec.add_development_dependency "yard", "~> 0.8.7"
35
+ spec.add_development_dependency "guard-livereload", "~> 2.5"
36
+ end
@@ -0,0 +1,400 @@
1
+ require_relative "test_helper.rb"
2
+
3
+ class ConfigManagerTest < Minitest::Test
4
+
5
+ def test_config_manager_read_config
6
+ logger = Logger.new("/dev/null")
7
+ config_path = "config/file/path"
8
+ io = Minitest::Mock.new
9
+ io.expect(:read, good_config.to_json)
10
+ config = nil
11
+ File.stub(:open, io) do
12
+ config = RokuBuilder::ConfigManager.get_config(config: config_path, logger: logger)
13
+ end
14
+ io.verify
15
+ assert_equal :roku, config[:devices][:default], :roku
16
+ assert_equal :project1, config[:projects][:default], :project1
17
+ end
18
+
19
+ def test_config_manager_validate_devices
20
+ logger = Logger.new("/dev/null")
21
+ config = good_config
22
+ config[:devices] = nil
23
+ codes = RokuBuilder::ConfigManager.validate_config(config: config, logger: logger)
24
+ assert_equal [1], codes
25
+ end
26
+
27
+ def test_config_manager_validate_devices_default
28
+ logger = Logger.new("/dev/null")
29
+ config = good_config
30
+ config[:devices][:default] = nil
31
+ codes = RokuBuilder::ConfigManager.validate_config(config: config, logger: logger)
32
+ assert_equal [2], codes
33
+ end
34
+
35
+ def test_config_manager_validate_devices_default_is_symbol
36
+ logger = Logger.new("/dev/null")
37
+ config = good_config
38
+ config[:devices][:default] = "bad"
39
+ codes = RokuBuilder::ConfigManager.validate_config(config: config, logger: logger)
40
+ assert_equal [3], codes
41
+ end
42
+
43
+ def test_config_manager_validate_device_ip
44
+ logger = Logger.new("/dev/null")
45
+ config = good_config
46
+ config[:devices][:roku][:ip] = nil
47
+ codes = RokuBuilder::ConfigManager.validate_config(config: config, logger: logger)
48
+ assert_equal [7], codes
49
+ end
50
+
51
+ def test_config_manager_validate_device_ip_empty
52
+ logger = Logger.new("/dev/null")
53
+ config = good_config
54
+ config[:devices][:roku][:ip] = ""
55
+ codes = RokuBuilder::ConfigManager.validate_config(config: config, logger: logger)
56
+ assert_equal [7], codes
57
+ end
58
+
59
+ def test_config_manager_validate_device_ip_default_value
60
+ logger = Logger.new("/dev/null")
61
+ config = good_config
62
+ config[:devices][:roku][:ip] = "xxx.xxx.xxx.xxx"
63
+ codes = RokuBuilder::ConfigManager.validate_config(config: config, logger: logger)
64
+ assert_equal [7], codes
65
+ end
66
+
67
+ def test_config_manager_validate_device_user
68
+ logger = Logger.new("/dev/null")
69
+ config = good_config
70
+ config[:devices][:roku][:user] = nil
71
+ codes = RokuBuilder::ConfigManager.validate_config(config: config, logger: logger)
72
+ assert_equal [8], codes
73
+ end
74
+
75
+ def test_config_manager_validate_device_user_empty
76
+ logger = Logger.new("/dev/null")
77
+ config = good_config
78
+ config[:devices][:roku][:user] = ""
79
+ codes = RokuBuilder::ConfigManager.validate_config(config: config, logger: logger)
80
+ assert_equal [8], codes
81
+ end
82
+
83
+ def test_config_manager_validate_device_user_default_value
84
+ logger = Logger.new("/dev/null")
85
+ config = good_config
86
+ config[:devices][:roku][:user] = "<username>"
87
+ codes = RokuBuilder::ConfigManager.validate_config(config: config, logger: logger)
88
+ assert_equal [8], codes
89
+ end
90
+
91
+ def test_config_manager_validate_device_password
92
+ logger = Logger.new("/dev/null")
93
+ config = good_config
94
+ config[:devices][:roku][:password] = nil
95
+ codes = RokuBuilder::ConfigManager.validate_config(config: config, logger: logger)
96
+ assert_equal [9], codes
97
+ end
98
+
99
+ def test_config_manager_validate_device_password_empty
100
+ logger = Logger.new("/dev/null")
101
+ config = good_config
102
+ config[:devices][:roku][:password] = ""
103
+ codes = RokuBuilder::ConfigManager.validate_config(config: config, logger: logger)
104
+ assert_equal [9], codes
105
+ end
106
+
107
+ def test_config_manager_validate_device_password_default_value
108
+ logger = Logger.new("/dev/null")
109
+ config = good_config
110
+ config[:devices][:roku][:password] = "<password>"
111
+ codes = RokuBuilder::ConfigManager.validate_config(config: config, logger: logger)
112
+ assert_equal [9], codes
113
+ end
114
+
115
+ def test_config_manager_validate_projects
116
+ logger = Logger.new("/dev/null")
117
+ config = good_config
118
+ config[:projects] = nil
119
+ codes = RokuBuilder::ConfigManager.validate_config(config: config, logger: logger)
120
+ assert_equal [4], codes
121
+ end
122
+
123
+ def test_config_manager_validate_projects_default
124
+ logger = Logger.new("/dev/null")
125
+ config = good_config
126
+ config[:projects][:default] = nil
127
+ codes = RokuBuilder::ConfigManager.validate_config(config: config, logger: logger)
128
+ assert_equal [5], codes
129
+ end
130
+
131
+ def test_config_manager_validate_projects_default_default_value
132
+ logger = Logger.new("/dev/null")
133
+ config = good_config
134
+ config[:projects][:default] = "<project id>".to_sym
135
+ codes = RokuBuilder::ConfigManager.validate_config(config: config, logger: logger)
136
+ assert_equal [5], codes
137
+ end
138
+
139
+ def test_config_manager_validate_projects_default_is_symbol
140
+ logger = Logger.new("/dev/null")
141
+ config = good_config
142
+ config[:projects][:default] = "project_id"
143
+ codes = RokuBuilder::ConfigManager.validate_config(config: config, logger: logger)
144
+ assert_equal [6], codes
145
+ end
146
+
147
+ def test_config_manager_validate_project_app_name
148
+ logger = Logger.new("/dev/null")
149
+ config = good_config
150
+ config[:projects][:project1][:app_name] = nil
151
+ codes = RokuBuilder::ConfigManager.validate_config(config: config, logger: logger)
152
+ assert_equal [10], codes
153
+ end
154
+
155
+ def test_config_manager_validate_project_directory
156
+ logger = Logger.new("/dev/null")
157
+ config = good_config
158
+ config[:projects][:project1][:directory] = nil
159
+ codes = RokuBuilder::ConfigManager.validate_config(config: config, logger: logger)
160
+ assert_equal [11], codes
161
+ end
162
+
163
+ def test_config_manager_validate_project_folders
164
+ logger = Logger.new("/dev/null")
165
+ config = good_config
166
+ config[:projects][:project1][:folders] = nil
167
+ codes = RokuBuilder::ConfigManager.validate_config(config: config, logger: logger)
168
+ assert_equal [12], codes
169
+ end
170
+
171
+ def test_config_manager_validate_project_folders_is_array
172
+ logger = Logger.new("/dev/null")
173
+ config = good_config
174
+ config[:projects][:project1][:folders] = "Folders"
175
+ codes = RokuBuilder::ConfigManager.validate_config(config: config, logger: logger)
176
+ assert_equal [13], codes
177
+ end
178
+
179
+ def test_config_manager_validate_project_files
180
+ logger = Logger.new("/dev/null")
181
+ config = good_config
182
+ config[:projects][:project1][:files] = nil
183
+ codes = RokuBuilder::ConfigManager.validate_config(config: config, logger: logger)
184
+ assert_equal [14], codes
185
+ end
186
+
187
+ def test_config_manager_validate_project_filess_is_array
188
+ logger = Logger.new("/dev/null")
189
+ config = good_config
190
+ config[:projects][:project1][:files] = "Files"
191
+ codes = RokuBuilder::ConfigManager.validate_config(config: config, logger: logger)
192
+ assert_equal [15], codes
193
+ end
194
+
195
+ def test_config_manager_edit_ip
196
+ logger = Logger.new("/dev/null")
197
+ config_path = "config/file/path"
198
+ args = {
199
+ config: config_path,
200
+ options: "ip:192.168.0.200",
201
+ device: :roku,
202
+ project: nil,
203
+ stage: nil,
204
+ logger: logger
205
+ }
206
+ new_config = good_config
207
+ new_config[:devices][:roku][:ip] = "192.168.0.200"
208
+
209
+ io = Minitest::Mock.new
210
+ io.expect(:read, good_config.to_json)
211
+ io.expect(:write, nil, [JSON.pretty_generate(new_config)])
212
+ io.expect(:close, nil)
213
+ config = nil
214
+ File.stub(:open, io) do
215
+ RokuBuilder::ConfigManager.edit_config(**args)
216
+ end
217
+ io.verify
218
+ end
219
+
220
+ def test_config_manager_edit_user
221
+ logger = Logger.new("/dev/null")
222
+ config_path = "config/file/path"
223
+ args = {
224
+ config: config_path,
225
+ options: "user:new_user",
226
+ device: "roku",
227
+ project: nil,
228
+ stage: nil,
229
+ logger: logger
230
+ }
231
+ new_config = good_config
232
+ new_config[:devices][:roku][:user] = "new_user"
233
+
234
+ io = Minitest::Mock.new
235
+ io.expect(:read, good_config.to_json)
236
+ io.expect(:write, nil, [JSON.pretty_generate(new_config)])
237
+ io.expect(:close, nil)
238
+ config = nil
239
+ File.stub(:open, io) do
240
+ RokuBuilder::ConfigManager.edit_config(**args)
241
+ end
242
+ io.verify
243
+ end
244
+
245
+ def test_config_manager_edit_password
246
+ logger = Logger.new("/dev/null")
247
+ config_path = "config/file/path"
248
+ args = {
249
+ config: config_path,
250
+ options: "password:new_password",
251
+ device: nil,
252
+ project: nil,
253
+ stage: nil,
254
+ logger: logger
255
+ }
256
+ new_config = good_config
257
+ new_config[:devices][:roku][:password] = "new_password"
258
+
259
+ io = Minitest::Mock.new
260
+ io.expect(:read, good_config.to_json)
261
+ io.expect(:write, nil, [JSON.pretty_generate(new_config)])
262
+ io.expect(:close, nil)
263
+ config = nil
264
+ File.stub(:open, io) do
265
+ RokuBuilder::ConfigManager.edit_config(**args)
266
+ end
267
+ io.verify
268
+ end
269
+
270
+ def test_config_manager_edit_app_name
271
+ logger = Logger.new("/dev/null")
272
+ config_path = "config/file/path"
273
+ args = {
274
+ config: config_path,
275
+ options: "app_name:new name",
276
+ device: nil,
277
+ project: :project1,
278
+ stage: nil,
279
+ logger: logger
280
+ }
281
+ new_config = good_config
282
+ new_config[:projects][:project1][:app_name] = "new name"
283
+
284
+ io = Minitest::Mock.new
285
+ io.expect(:read, good_config.to_json)
286
+ io.expect(:write, nil, [JSON.pretty_generate(new_config)])
287
+ io.expect(:close, nil)
288
+ config = nil
289
+ File.stub(:open, io) do
290
+ RokuBuilder::ConfigManager.edit_config(**args)
291
+ end
292
+ io.verify
293
+ end
294
+
295
+ def test_config_manager_edit_directory
296
+ logger = Logger.new("/dev/null")
297
+ config_path = "config/file/path"
298
+ args = {
299
+ config: config_path,
300
+ options: "directory:new/directory/path",
301
+ device: nil,
302
+ project: "project1",
303
+ stage: nil,
304
+ logger: logger
305
+ }
306
+ new_config = good_config
307
+ new_config[:projects][:project1][:directory] = "new/directory/path"
308
+
309
+ io = Minitest::Mock.new
310
+ io.expect(:read, good_config.to_json)
311
+ io.expect(:write, nil, [JSON.pretty_generate(new_config)])
312
+ io.expect(:close, nil)
313
+ config = nil
314
+ File.stub(:open, io) do
315
+ RokuBuilder::ConfigManager.edit_config(**args)
316
+ end
317
+ io.verify
318
+ end
319
+
320
+ def test_config_manager_edit_branch
321
+ logger = Logger.new("/dev/null")
322
+ config_path = "config/file/path"
323
+ args = {
324
+ config: config_path,
325
+ options: "branch:new-branch",
326
+ device: nil,
327
+ project: nil,
328
+ stage: :production,
329
+ logger: logger
330
+ }
331
+ new_config = good_config
332
+ new_config[:projects][:project1][:stages][:production][:branch] = "new-branch"
333
+
334
+ io = Minitest::Mock.new
335
+ io.expect(:read, good_config.to_json)
336
+ io.expect(:write, nil, [JSON.pretty_generate(new_config)])
337
+ io.expect(:close, nil)
338
+ config = nil
339
+ File.stub(:open, io) do
340
+ RokuBuilder::ConfigManager.edit_config(**args)
341
+ end
342
+ io.verify
343
+ end
344
+
345
+ def test_config_manager_edit_default_stage
346
+ logger = Logger.new("/dev/null")
347
+ config_path = "config/file/path"
348
+ args = {
349
+ config: config_path,
350
+ options: "branch:new-branch",
351
+ device: nil,
352
+ project: nil,
353
+ stage: nil,
354
+ logger: logger
355
+ }
356
+ new_config = good_config
357
+ new_config[:projects][:project1][:stages][:production][:branch] = "new-branch"
358
+
359
+ io = Minitest::Mock.new
360
+ io.expect(:read, good_config.to_json)
361
+ io.expect(:write, nil, [JSON.pretty_generate(new_config)])
362
+ io.expect(:close, nil)
363
+ config = nil
364
+ File.stub(:open, io) do
365
+ RokuBuilder::ConfigManager.edit_config(**args)
366
+ end
367
+ io.verify
368
+ end
369
+
370
+ def good_config
371
+ {
372
+ devices: {
373
+ default: :roku,
374
+ roku: {
375
+ ip: "192.168.0.100",
376
+ user: "user",
377
+ password: "password"
378
+ }
379
+ },
380
+ projects: {
381
+ default: :project1,
382
+ project1: {
383
+ directory: "<path/to/repo>",
384
+ folders: ["resources","source"],
385
+ files: ["manifest"],
386
+ app_name: "<app name>",
387
+ stages:{
388
+ production: {
389
+ branch: "production",
390
+ key: {
391
+ keyed_pkg: "<path/to/signed/pkg>",
392
+ password: "<password for pkg>"
393
+ }
394
+ }
395
+ }
396
+ }
397
+ }
398
+ }
399
+ end
400
+ end