MuranoCLI 2.0.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (151) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +28 -0
  3. data/.rspec +2 -0
  4. data/.travis.yml +21 -0
  5. data/Gemfile +27 -0
  6. data/LICENSE.txt +19 -0
  7. data/MuranoCLI.gemspec +50 -0
  8. data/MuranoCLI.iss +50 -0
  9. data/README.markdown +208 -0
  10. data/Rakefile +188 -0
  11. data/TODO.taskpaper +122 -0
  12. data/bin/mr +8 -0
  13. data/bin/murano +84 -0
  14. data/docs/demo.md +109 -0
  15. data/lib/MrMurano/Account.rb +211 -0
  16. data/lib/MrMurano/Config-Migrate.rb +47 -0
  17. data/lib/MrMurano/Config.rb +286 -0
  18. data/lib/MrMurano/Mock.rb +63 -0
  19. data/lib/MrMurano/Product-1P-Device.rb +145 -0
  20. data/lib/MrMurano/Product-Resources.rb +195 -0
  21. data/lib/MrMurano/Product.rb +358 -0
  22. data/lib/MrMurano/ProjectFile.rb +349 -0
  23. data/lib/MrMurano/Solution-Cors.rb +46 -0
  24. data/lib/MrMurano/Solution-Endpoint.rb +177 -0
  25. data/lib/MrMurano/Solution-File.rb +150 -0
  26. data/lib/MrMurano/Solution-ServiceConfig.rb +140 -0
  27. data/lib/MrMurano/Solution-Services.rb +326 -0
  28. data/lib/MrMurano/Solution-Users.rb +129 -0
  29. data/lib/MrMurano/Solution.rb +59 -0
  30. data/lib/MrMurano/SubCmdGroupContext.rb +49 -0
  31. data/lib/MrMurano/SyncUpDown.rb +565 -0
  32. data/lib/MrMurano/commands/assign.rb +57 -0
  33. data/lib/MrMurano/commands/businessList.rb +45 -0
  34. data/lib/MrMurano/commands/completion.rb +152 -0
  35. data/lib/MrMurano/commands/config.rb +67 -0
  36. data/lib/MrMurano/commands/content.rb +130 -0
  37. data/lib/MrMurano/commands/cors.rb +30 -0
  38. data/lib/MrMurano/commands/domain.rb +17 -0
  39. data/lib/MrMurano/commands/gb.rb +33 -0
  40. data/lib/MrMurano/commands/init.rb +138 -0
  41. data/lib/MrMurano/commands/keystore.rb +157 -0
  42. data/lib/MrMurano/commands/logs.rb +78 -0
  43. data/lib/MrMurano/commands/mock.rb +63 -0
  44. data/lib/MrMurano/commands/password.rb +88 -0
  45. data/lib/MrMurano/commands/postgresql.rb +41 -0
  46. data/lib/MrMurano/commands/product.rb +14 -0
  47. data/lib/MrMurano/commands/productCreate.rb +39 -0
  48. data/lib/MrMurano/commands/productDelete.rb +33 -0
  49. data/lib/MrMurano/commands/productDevice.rb +84 -0
  50. data/lib/MrMurano/commands/productDeviceIdCmds.rb +86 -0
  51. data/lib/MrMurano/commands/productList.rb +45 -0
  52. data/lib/MrMurano/commands/productWrite.rb +27 -0
  53. data/lib/MrMurano/commands/show.rb +80 -0
  54. data/lib/MrMurano/commands/solution.rb +14 -0
  55. data/lib/MrMurano/commands/solutionCreate.rb +39 -0
  56. data/lib/MrMurano/commands/solutionDelete.rb +34 -0
  57. data/lib/MrMurano/commands/solutionList.rb +45 -0
  58. data/lib/MrMurano/commands/status.rb +92 -0
  59. data/lib/MrMurano/commands/sync.rb +60 -0
  60. data/lib/MrMurano/commands/timeseries.rb +115 -0
  61. data/lib/MrMurano/commands/tsdb.rb +271 -0
  62. data/lib/MrMurano/commands/usage.rb +23 -0
  63. data/lib/MrMurano/commands/zshcomplete.erb +112 -0
  64. data/lib/MrMurano/commands.rb +32 -0
  65. data/lib/MrMurano/hash.rb +20 -0
  66. data/lib/MrMurano/http.rb +153 -0
  67. data/lib/MrMurano/makePretty.rb +75 -0
  68. data/lib/MrMurano/schema/pf-v1.0.0.yaml +114 -0
  69. data/lib/MrMurano/schema/sf-v0.2.0.yaml +77 -0
  70. data/lib/MrMurano/schema/sf-v0.3.0.yaml +78 -0
  71. data/lib/MrMurano/template/mock.erb +9 -0
  72. data/lib/MrMurano/template/projectFile.murano.erb +81 -0
  73. data/lib/MrMurano/verbosing.rb +99 -0
  74. data/lib/MrMurano/version.rb +4 -0
  75. data/lib/MrMurano.rb +20 -0
  76. data/spec/Account-Passwords_spec.rb +242 -0
  77. data/spec/Account_spec.rb +272 -0
  78. data/spec/ConfigFile_spec.rb +50 -0
  79. data/spec/ConfigMigrate_spec.rb +89 -0
  80. data/spec/Config_spec.rb +409 -0
  81. data/spec/Http_spec.rb +204 -0
  82. data/spec/MakePretties_spec.rb +118 -0
  83. data/spec/Mock_spec.rb +53 -0
  84. data/spec/ProductBase_spec.rb +113 -0
  85. data/spec/ProductContent_spec.rb +162 -0
  86. data/spec/ProductResources_spec.rb +329 -0
  87. data/spec/Product_1P_Device_spec.rb +202 -0
  88. data/spec/Product_1P_RPC_spec.rb +175 -0
  89. data/spec/Product_spec.rb +153 -0
  90. data/spec/ProjectFile_spec.rb +324 -0
  91. data/spec/Solution-Cors_spec.rb +164 -0
  92. data/spec/Solution-Endpoint_spec.rb +581 -0
  93. data/spec/Solution-File_spec.rb +212 -0
  94. data/spec/Solution-ServiceConfig_spec.rb +202 -0
  95. data/spec/Solution-ServiceDevice_spec.rb +176 -0
  96. data/spec/Solution-ServiceEventHandler_spec.rb +385 -0
  97. data/spec/Solution-ServiceModules_spec.rb +465 -0
  98. data/spec/Solution-UsersRoles_spec.rb +207 -0
  99. data/spec/Solution_spec.rb +92 -0
  100. data/spec/SyncRoot_spec.rb +83 -0
  101. data/spec/SyncUpDown_spec.rb +495 -0
  102. data/spec/Verbosing_spec.rb +279 -0
  103. data/spec/_workspace.rb +27 -0
  104. data/spec/cmd_assign_spec.rb +51 -0
  105. data/spec/cmd_business_spec.rb +59 -0
  106. data/spec/cmd_common.rb +72 -0
  107. data/spec/cmd_config_spec.rb +68 -0
  108. data/spec/cmd_content_spec.rb +71 -0
  109. data/spec/cmd_cors_spec.rb +50 -0
  110. data/spec/cmd_device_spec.rb +96 -0
  111. data/spec/cmd_domain_spec.rb +32 -0
  112. data/spec/cmd_init_spec.rb +30 -0
  113. data/spec/cmd_keystore_spec.rb +97 -0
  114. data/spec/cmd_password_spec.rb +62 -0
  115. data/spec/cmd_status_spec.rb +239 -0
  116. data/spec/cmd_syncdown_spec.rb +86 -0
  117. data/spec/cmd_syncup_spec.rb +62 -0
  118. data/spec/cmd_usage_spec.rb +36 -0
  119. data/spec/fixtures/.mrmuranorc +9 -0
  120. data/spec/fixtures/ProjectFiles/invalid.yaml +9 -0
  121. data/spec/fixtures/ProjectFiles/only_meta.yaml +24 -0
  122. data/spec/fixtures/ProjectFiles/with_routes.yaml +27 -0
  123. data/spec/fixtures/SolutionFiles/0.2.0.json +20 -0
  124. data/spec/fixtures/SolutionFiles/0.2.0_invalid.json +18 -0
  125. data/spec/fixtures/SolutionFiles/0.2.json +21 -0
  126. data/spec/fixtures/SolutionFiles/0.3.0.json +20 -0
  127. data/spec/fixtures/SolutionFiles/0.3.0_invalid.json +19 -0
  128. data/spec/fixtures/SolutionFiles/0.3.json +20 -0
  129. data/spec/fixtures/SolutionFiles/basic.json +20 -0
  130. data/spec/fixtures/SolutionFiles/secret.json +6 -0
  131. data/spec/fixtures/configfile +9 -0
  132. data/spec/fixtures/dumped_config +42 -0
  133. data/spec/fixtures/mrmuranorc_deleted_bob +8 -0
  134. data/spec/fixtures/mrmuranorc_tool_bob +3 -0
  135. data/spec/fixtures/product_spec_files/example.exoline.spec.yaml +116 -0
  136. data/spec/fixtures/product_spec_files/example.murano.spec.yaml +14 -0
  137. data/spec/fixtures/product_spec_files/gwe.exoline.spec.yaml +21 -0
  138. data/spec/fixtures/product_spec_files/gwe.murano.spec.yaml +16 -0
  139. data/spec/fixtures/product_spec_files/lightbulb-no-state.yaml +11 -0
  140. data/spec/fixtures/product_spec_files/lightbulb.yaml +14 -0
  141. data/spec/fixtures/roles-three.yaml +11 -0
  142. data/spec/fixtures/syncable_content/assets/icon.png +0 -0
  143. data/spec/fixtures/syncable_content/assets/index.html +0 -0
  144. data/spec/fixtures/syncable_content/assets/js/script.js +0 -0
  145. data/spec/fixtures/syncable_content/modules/table_util.lua +58 -0
  146. data/spec/fixtures/syncable_content/routes/manyRoutes.lua +11 -0
  147. data/spec/fixtures/syncable_content/routes/singleRoute.lua +5 -0
  148. data/spec/fixtures/syncable_content/services/devdata.lua +18 -0
  149. data/spec/fixtures/syncable_content/services/timers.lua +4 -0
  150. data/spec/spec_helper.rb +119 -0
  151. metadata +498 -0
@@ -0,0 +1,272 @@
1
+ require 'MrMurano/version'
2
+ require 'MrMurano/Config'
3
+ require 'MrMurano/Account'
4
+ require 'highline/import'
5
+ require '_workspace'
6
+
7
+ RSpec.describe MrMurano::Account, "token" do
8
+ include_context "WORKSPACE"
9
+ before(:example) do
10
+ $cfg = MrMurano::Config.new
11
+ $cfg.load
12
+ $cfg['net.host'] = 'bizapi.hosted.exosite.io'
13
+ $cfg['business.id'] = 'XYZxyz'
14
+ $cfg['product.id'] = 'XYZ'
15
+
16
+ @acc = MrMurano::Account.new
17
+ end
18
+
19
+ after(:example) do
20
+ @acc.token_reset
21
+ end
22
+
23
+ context "Get login info" do
24
+ before(:example) do
25
+ @pswd = instance_double("MrMurano::Passwords")
26
+ allow(@pswd).to receive(:load).and_return(nil)
27
+ allow(@pswd).to receive(:save).and_return(nil)
28
+ allow(MrMurano::Passwords).to receive(:new).and_return(@pswd)
29
+ end
30
+
31
+ it "Asks for nothing" do
32
+ $cfg['user.name'] = "bob"
33
+ expect(@pswd).to receive(:get).once.and_return("built")
34
+
35
+ ret = @acc._loginInfo
36
+ expect(ret).to eq({
37
+ :email => "bob", :password=>"built"
38
+ })
39
+ end
40
+
41
+ it "Asks for user name" do
42
+ $cfg['user.name'] = nil
43
+ expect($terminal).to receive(:ask).once.and_return('bob')
44
+ expect(@acc).to receive(:error).once
45
+ expect($cfg).to receive(:set).with('user.name', 'bob', :user).once.and_call_original
46
+ expect(@pswd).to receive(:get).once.and_return("built")
47
+
48
+ ret = @acc._loginInfo
49
+ expect(ret).to eq({
50
+ :email => "bob", :password=>"built"
51
+ })
52
+ end
53
+
54
+ it "Asks for password" do
55
+ $cfg['user.name'] = "bob"
56
+ expect(@pswd).to receive(:get).with('bizapi.hosted.exosite.io','bob').once.and_return(nil)
57
+ expect(@acc).to receive(:error).once
58
+ expect($terminal).to receive(:ask).once.and_return('dog')
59
+ expect(@pswd).to receive(:set).once.with('bizapi.hosted.exosite.io','bob','dog')
60
+
61
+ ret = @acc._loginInfo
62
+ expect(ret).to eq({
63
+ :email => "bob", :password=>"dog"
64
+ })
65
+ end
66
+ end
67
+
68
+ context "token" do
69
+ before(:example) do
70
+ allow(@acc).to receive(:_loginInfo).and_return({:email=>'bob',:password=>'v'})
71
+ end
72
+
73
+ it "gets a token" do
74
+ stub_request(:post, "https://bizapi.hosted.exosite.io/api:1/token/").
75
+ with(:body => {:email=>'bob', :password=>'v'}.to_json).
76
+ to_return(body: {:token=>"ABCDEFGHIJKLMNOP"}.to_json )
77
+
78
+ ret = @acc.token
79
+ expect(ret).to eq("ABCDEFGHIJKLMNOP")
80
+ end
81
+
82
+ it "gets an error" do
83
+ stub_request(:post, "https://bizapi.hosted.exosite.io/api:1/token/").
84
+ with(:body => {:email=>'bob', :password=>'v'}.to_json).
85
+ to_return(status: 401, body: {}.to_json )
86
+
87
+ expect(@acc).to receive(:error).twice.and_return(nil)
88
+ ret = @acc.token
89
+ expect(ret).to be_nil
90
+ end
91
+
92
+ it "uses existing token" do
93
+ @acc.token_reset("quxx")
94
+ ret = @acc.token
95
+ expect(ret).to eq("quxx")
96
+ end
97
+
98
+ it "uses existing token, even with new instance" do
99
+ @acc.token_reset("quxx")
100
+ acc = MrMurano::Account.new
101
+ ret = acc.token
102
+ expect(ret).to eq("quxx")
103
+ end
104
+ end
105
+ end
106
+
107
+ RSpec.describe MrMurano::Account do
108
+ include_context "WORKSPACE"
109
+ before(:example) do
110
+ $cfg = MrMurano::Config.new
111
+ $cfg.load
112
+ $cfg['net.host'] = 'bizapi.hosted.exosite.io'
113
+ $cfg['business.id'] = 'XYZxyz'
114
+ $cfg['product.id'] = 'XYZ'
115
+
116
+ @acc = MrMurano::Account.new
117
+ allow(@acc).to receive(:token).and_return("TTTTTTTTTT")
118
+ end
119
+
120
+ it "initializes" do
121
+ uri = @acc.endPoint('')
122
+ expect(uri.to_s).to eq("https://bizapi.hosted.exosite.io/api:1/")
123
+ end
124
+
125
+ context "lists business" do
126
+ it "for user.name" do
127
+ bizlist = [{"bizid"=>"XXX","role"=>"admin","name"=>"MPS"},
128
+ {"bizid"=>"YYY","role"=>"admin","name"=>"MAE"}]
129
+ stub_request(:get, "https://bizapi.hosted.exosite.io/api:1/user/BoB@place.net/membership/").
130
+ to_return(body: bizlist )
131
+
132
+ $cfg['user.name'] = 'BoB@place.net'
133
+ ret = @acc.businesses
134
+ expect(ret).to eq(bizlist)
135
+ end
136
+
137
+ it "askes for account when missing" do
138
+ bizlist = [{"bizid"=>"XXX","role"=>"admin","name"=>"MPS"},
139
+ {"bizid"=>"YYY","role"=>"admin","name"=>"MAE"}]
140
+ stub_request(:get, "https://bizapi.hosted.exosite.io/api:1/user/BoB@place.net/membership/").
141
+ to_return(body: bizlist )
142
+
143
+ $cfg['user.name'] = nil
144
+ expect(@acc).to receive(:_loginInfo) do |arg|
145
+ $cfg['user.name'] = 'BoB@place.net'
146
+ end
147
+
148
+ ret = @acc.businesses
149
+ expect(ret).to eq(bizlist)
150
+ end
151
+ end
152
+
153
+ it "lists products" do
154
+ prdlist = [{"bizid"=>"XYZxyz","type"=>"onepModel","pid"=>"ABC","modelId"=>"cde","label"=>"fts"},
155
+ {"bizid"=>"XYZxyz","type"=>"onepModel","pid"=>"fgh","modelId"=>"ijk","label"=>"lua-test"}]
156
+ stub_request(:get, "https://bizapi.hosted.exosite.io/api:1/business/XYZxyz/product/").
157
+ to_return(body: prdlist )
158
+
159
+ ret = @acc.products
160
+ expect(ret).to eq(prdlist)
161
+ end
162
+
163
+ it "lists products; without biz.id" do
164
+ allow($cfg).to receive(:get).with('business.id').and_return(nil)
165
+ expect { @acc.products }.to raise_error("Missing Business ID")
166
+ end
167
+
168
+ it "creates product" do
169
+ stub_request(:post, "https://bizapi.hosted.exosite.io/api:1/business/XYZxyz/product/").
170
+ with(:body => {:label=>'ONe', :type=>'onepModel'}).
171
+ to_return(body: "" )
172
+
173
+ ret = @acc.new_product("ONe")
174
+ expect(ret).to eq({})
175
+ end
176
+
177
+ it "creates product; without biz.id" do
178
+ allow($cfg).to receive(:get).with('business.id').and_return(nil)
179
+ expect { @acc.new_product("ONe") }.to raise_error("Missing Business ID")
180
+ end
181
+
182
+ it "deletes product" do
183
+ stub_request(:delete, "https://bizapi.hosted.exosite.io/api:1/business/XYZxyz/product/ONe").
184
+ to_return(body: "" )
185
+
186
+ ret = @acc.delete_product("ONe")
187
+ expect(ret).to eq({})
188
+ end
189
+
190
+ it "deletes product; without biz.id" do
191
+ allow($cfg).to receive(:get).with('business.id').and_return(nil)
192
+ expect { @acc.delete_product("ONe") }.to raise_error("Missing Business ID")
193
+ end
194
+
195
+
196
+ it "lists solutions" do
197
+ sollist = [{"bizid"=>"XYZxyz",
198
+ "type"=>"dataApi",
199
+ "domain"=>"two.apps.exosite.io",
200
+ "apiId"=>"abc",
201
+ "sid"=>"def"},
202
+ {"bizid"=>"XYZxyz",
203
+ "type"=>"dataApi",
204
+ "domain"=>"one.apps.exosite.io",
205
+ "apiId"=>"ghi",
206
+ "sid"=>"jkl"}]
207
+ stub_request(:get, "https://bizapi.hosted.exosite.io/api:1/business/XYZxyz/solution/").
208
+ to_return(body: sollist )
209
+
210
+ ret = @acc.solutions
211
+ expect(ret).to eq(sollist)
212
+ end
213
+
214
+ it "lists solutions; without biz.id" do
215
+ allow($cfg).to receive(:get).with('business.id').and_return(nil)
216
+ expect { @acc.solutions }.to raise_error("Missing Business ID")
217
+ end
218
+
219
+ it "creates solution" do
220
+ stub_request(:post, "https://bizapi.hosted.exosite.io/api:1/business/XYZxyz/solution/").
221
+ with(:body => {:label=>'one', :type=>'dataApi'}).
222
+ to_return(body: "" )
223
+
224
+ ret = @acc.new_solution("one")
225
+ expect(ret).to eq({})
226
+ end
227
+
228
+ it "creates solution; with upper case" do
229
+ stub_request(:post, "https://bizapi.hosted.exosite.io/api:1/business/XYZxyz/solution/").
230
+ with(:body => {:label=>'ONe', :type=>'dataApi'}).
231
+ to_return(body: "" )
232
+
233
+ expect { @acc.new_solution("ONe") }.to_not raise_error
234
+ end
235
+
236
+ it "creates solution; with numbers and dashes" do
237
+ stub_request(:post, "https://bizapi.hosted.exosite.io/api:1/business/XYZxyz/solution/").
238
+ with(:body => {:label=>'ONe-8796-gkl', :type=>'dataApi'}).
239
+ to_return(body: "" )
240
+
241
+ expect { @acc.new_solution("ONe-8796-gkl") }.to_not raise_error
242
+ end
243
+
244
+ it "creates solution; that is too long" do
245
+ expect { @acc.new_solution("o"*70) }.to raise_error("Solution name must be a valid domain name component")
246
+ end
247
+
248
+ it "creates solution; with underscore" do
249
+ expect { @acc.new_solution("one_two") }.to raise_error("Solution name must be a valid domain name component")
250
+ end
251
+
252
+ it "creates solution; without biz.id" do
253
+ allow($cfg).to receive(:get).with('business.id').and_return(nil)
254
+ expect { @acc.new_solution("one") }.to raise_error("Missing Business ID")
255
+ end
256
+
257
+ it "deletes solution" do
258
+ stub_request(:delete, "https://bizapi.hosted.exosite.io/api:1/business/XYZxyz/solution/one").
259
+ to_return(body: "" )
260
+
261
+ ret = @acc.delete_solution("one")
262
+ expect(ret).to eq({})
263
+ end
264
+
265
+ it "deletes solution; without biz.id" do
266
+ allow($cfg).to receive(:get).with('business.id').and_return(nil)
267
+ expect { @acc.delete_solution("one") }.to raise_error("Missing Business ID")
268
+ end
269
+
270
+ end
271
+
272
+ # vim: set ai et sw=2 ts=2 :
@@ -0,0 +1,50 @@
1
+ require 'MrMurano/version'
2
+ require 'MrMurano/Config'
3
+ require 'tempfile'
4
+
5
+ RSpec.describe MrMurano::Config::ConfigFile do
6
+ it "Creates a file" do
7
+ tmpfile = Dir.tmpdir + '/cfgtest' # This way because Tempfile.new creates.
8
+ begin
9
+ cf = MrMurano::Config::ConfigFile.new(:user, tmpfile)
10
+ cf.write
11
+
12
+ expect(FileTest.exist?(tmpfile))
13
+ unless Gem.win_platform? then
14
+ expect(FileTest.world_readable?(tmpfile)).to be(nil)
15
+ expect(FileTest.world_writable?(tmpfile)).to be(nil)
16
+ end
17
+ ensure
18
+ File.unlink(tmpfile) unless tmpfile.nil?
19
+ end
20
+ end
21
+
22
+ it ":internal does not write a file" do
23
+ tmpfile = Dir.tmpdir + '/cfgtest' # This way because Tempfile.new creates.
24
+ begin
25
+ MrMurano::Config::ConfigFile.new(:internal, tmpfile)
26
+ expect(FileTest.exist?(tmpfile)).to be(false)
27
+ ensure
28
+ File.unlink(tmpfile) if FileTest.exist?(tmpfile)
29
+ end
30
+ end
31
+ it ":defaults does not write a file" do
32
+ tmpfile = Dir.tmpdir + '/cfgtest' # This way because Tempfile.new creates.
33
+ begin
34
+ MrMurano::Config::ConfigFile.new(:defaults, tmpfile)
35
+ expect(FileTest.exist?(tmpfile)).to be(false)
36
+ ensure
37
+ File.unlink(tmpfile) if FileTest.exist?(tmpfile)
38
+ end
39
+ end
40
+
41
+ it "loads a file" do
42
+ cf = MrMurano::Config::ConfigFile.new(:project, 'spec/fixtures/configfile')
43
+ cf.load
44
+
45
+ expect(cf[:data]['solution']['id']).to eq('XXXXXXXXXX')
46
+ end
47
+
48
+ end
49
+
50
+ # vim: set ai et sw=2 ts=2 :
@@ -0,0 +1,89 @@
1
+ require 'MrMurano/version'
2
+ require 'MrMurano/Config-Migrate'
3
+ require 'highline/import'
4
+ require '_workspace'
5
+ #require 'tempfile'
6
+ #require 'erb'
7
+
8
+ RSpec.describe MrMurano::ConfigMigrate do
9
+ include_context "WORKSPACE"
10
+ before(:example) do
11
+ @saved_pwd = ENV['MURANO_PASSWORD']
12
+ ENV['MURANO_PASSWORD'] = nil
13
+
14
+ $cfg = MrMurano::Config.new
15
+ $cfg.load
16
+ $cfg['net.host'] = 'bizapi.hosted.exosite.io'
17
+
18
+ @lry = Pathname.new(@projectDir) + '.Solutionfile.secret'
19
+ FileUtils.copy(File.join(@testdir, 'spec/fixtures/SolutionFiles/secret.json'), @lry.to_path)
20
+
21
+ @mrt = MrMurano::ConfigMigrate.new
22
+
23
+ @stdsaved = [$stdout, $stderr]
24
+ $stdout, $stderr = [StringIO.new, StringIO.new]
25
+ end
26
+
27
+ after(:example) do
28
+ $stdout, $stderr = @stdsaved
29
+ ENV['MURANO_PASSWORD'] = @saved_pwd
30
+ end
31
+
32
+ it "imports all" do
33
+ @mrt.import_secret
34
+
35
+ expect($cfg['solution.id']).to eq('ABCDEFG')
36
+ expect($cfg['product.id']).to eq('HIJKLMNOP')
37
+ expect($cfg['user.name']).to eq('test@user.account')
38
+ pff = $cfg.file_at('passwords', :user)
39
+ pwd = MrMurano::Passwords.new(pff)
40
+ pwd.load
41
+ expect(pwd.get$cfg['net.host'], $cfg['user.name']).to eq('gibblygook')
42
+ expect($stdout.string).to eq('')
43
+ expect($stderr.string).to eq('')
44
+ end
45
+
46
+ it "imports over" do
47
+ $cfg['solution.id'] = '12'
48
+ $cfg['product.id'] = 'awdfvs'
49
+ $cfg['user.name'] = '3qrarvsa'
50
+ $cfg = MrMurano::Config.new
51
+ $cfg.load
52
+ $cfg['net.host'] = 'bizapi.hosted.exosite.io'
53
+
54
+ @mrt.import_secret
55
+
56
+ expect($cfg['solution.id']).to eq('ABCDEFG')
57
+ expect($cfg['product.id']).to eq('HIJKLMNOP')
58
+ expect($cfg['user.name']).to eq('test@user.account')
59
+ pff = $cfg.file_at('passwords', :user)
60
+ pwd = MrMurano::Passwords.new(pff)
61
+ pwd.load
62
+ expect(pwd.get$cfg['net.host'], $cfg['user.name']).to eq('gibblygook')
63
+ expect($stdout.string).to eq('')
64
+ expect($stderr.string).to eq('')
65
+ end
66
+
67
+ it "Asks about password differences" do
68
+ pff = $cfg.file_at('passwords', :user)
69
+ pwd = MrMurano::Passwords.new(pff)
70
+ pwd.set($cfg['net.host'], 'test@user.account', 'bob')
71
+ pwd.save
72
+
73
+ expect($terminal).to receive(:ask).with('A different password for this account already exists. Overwrite? N/y').and_return('y')
74
+
75
+ @mrt.import_secret
76
+
77
+ expect($cfg['solution.id']).to eq('ABCDEFG')
78
+ expect($cfg['product.id']).to eq('HIJKLMNOP')
79
+ expect($cfg['user.name']).to eq('test@user.account')
80
+ pff = $cfg.file_at('passwords', :user)
81
+ pwd = MrMurano::Passwords.new(pff)
82
+ pwd.load
83
+ expect(pwd.get$cfg['net.host'], $cfg['user.name']).to eq('gibblygook')
84
+ expect($stdout.string).to eq('')
85
+ expect($stderr.string).to eq('')
86
+ end
87
+
88
+ end
89
+ # vim: set ai et sw=2 ts=2 :
@@ -0,0 +1,409 @@
1
+ require 'MrMurano/version'
2
+ require 'MrMurano/Config'
3
+ require '_workspace'
4
+ require 'tempfile'
5
+ require 'erb'
6
+
7
+ RSpec.describe MrMurano::Config do
8
+
9
+ context "Basics " do
10
+ include_context "WORKSPACE"
11
+ it "Sets defaults" do
12
+ cfg = MrMurano::Config.new
13
+ cfg.load
14
+ # Don't check for all of them, just a few.
15
+ expect(cfg['files.default_page']).to eq('index.html')
16
+ expect(cfg.get('files.default_page', :defaults)).to eq('index.html')
17
+ expect(cfg['tool.debug']).to eq(false)
18
+ expect(cfg.get('tool.debug', :defaults)).to eq(false)
19
+ end
20
+
21
+ it "Sets internal values" do
22
+ cfg = MrMurano::Config.new
23
+ cfg.load
24
+
25
+ cfg['bob.test'] = 'twelve'
26
+
27
+ expect(cfg['bob.test']).to eq('twelve')
28
+ expect(cfg.get('bob.test', :internal)).to eq('twelve')
29
+ end
30
+
31
+ it "Sets tool values" do
32
+ cfg = MrMurano::Config.new
33
+ cfg.load
34
+
35
+ cfg['test'] = 'twelve'
36
+
37
+ expect(cfg['tool.test']).to eq('twelve')
38
+ expect(cfg.get('tool.test', :internal)).to eq('twelve')
39
+ end
40
+
41
+ it "Sets project values" do # This should write
42
+ cfg = MrMurano::Config.new
43
+ cfg.load
44
+
45
+ cfg.set('bob.test', 'twelve', :project)
46
+
47
+ expect(cfg['bob.test']).to eq('twelve')
48
+ expect(cfg.get('bob.test', :project)).to eq('twelve')
49
+
50
+ expect(FileTest.exist?(@projectDir + '.murano/config'))
51
+
52
+ #reload
53
+ cfg = MrMurano::Config.new
54
+ cfg.load
55
+ expect(cfg.get('bob.test', :project)).to eq('twelve')
56
+ end
57
+
58
+ it "Sets a user value" do
59
+ cfg = MrMurano::Config.new
60
+ cfg.load
61
+
62
+ cfg.set('bob.test', 'twelve', :user)
63
+
64
+ expect(cfg['bob.test']).to eq('twelve')
65
+ expect(cfg.get('bob.test', :user)).to eq('twelve')
66
+
67
+ expect(FileTest.exist?(ENV['HOME'] + '.murano/config'))
68
+
69
+ #reload
70
+ cfg = MrMurano::Config.new
71
+ cfg.load
72
+ expect(cfg.get('bob.test', :user)).to eq('twelve')
73
+ end
74
+
75
+ it "loads from a specific file" do
76
+ File.open(@projectDir + '/foo.cfg', 'w') do |io|
77
+ io << %{[test]
78
+ bob = test
79
+ }.gsub(/^\s\+/,'')
80
+ end
81
+
82
+ cfg = MrMurano::Config.new
83
+ cfg.load
84
+ cfg.load_specific(@projectDir + '/foo.cfg')
85
+
86
+ expect(cfg['test.bob']).to eq('test')
87
+ end
88
+
89
+ context "returns a path to a file in" do
90
+ it "project mrmurano dir" do
91
+ cfg = MrMurano::Config.new
92
+ cfg.load
93
+ path = cfg.file_at('testfile').realdirpath
94
+ want = Pathname.new(@projectDir + '/.murano/testfile').realdirpath
95
+
96
+ expect(path).to eq(want)
97
+ end
98
+
99
+ it "user mrmurano dir" do
100
+ cfg = MrMurano::Config.new
101
+ cfg.load
102
+ path = cfg.file_at('testfile', :user).realdirpath
103
+ want = Pathname.new(Dir.home + '/.murano/testfile').realdirpath
104
+
105
+ expect(path).to eq(want)
106
+ end
107
+
108
+ it "internal" do
109
+ cfg = MrMurano::Config.new
110
+ cfg.load
111
+ path = cfg.file_at('testfile', :internal)
112
+
113
+ expect(path).to eq(nil)
114
+ end
115
+
116
+ it "specified" do
117
+ cfg = MrMurano::Config.new
118
+ cfg.load
119
+ path = cfg.file_at('testfile', :specified)
120
+
121
+ expect(path).to eq(nil)
122
+ end
123
+
124
+ it "defaults" do
125
+ cfg = MrMurano::Config.new
126
+ cfg.load
127
+ path = cfg.file_at('testfile', :defaults)
128
+
129
+ expect(path).to eq(nil)
130
+ end
131
+ end
132
+
133
+ context "ENV['MURANO_CONFIGFILE']" do
134
+ after(:example) do
135
+ ENV['MURANO_CONFIGFILE'] = nil
136
+ ENV['MR_CONFIGFILE'] = nil
137
+ end
138
+
139
+ it "loads file in env" do
140
+ ENV['MURANO_CONFIGFILE'] = @tmpdir + '/home/test.config'
141
+ File.open(@tmpdir + '/home/test.config', 'w') do |io|
142
+ io << %{[test]
143
+ bob = test
144
+ }.gsub(/^\s\+/,'')
145
+ end
146
+
147
+ cfg = MrMurano::Config.new
148
+ cfg.load
149
+ expect(cfg['test.bob']).to eq('test')
150
+ end
151
+
152
+ it "will create file at env" do
153
+ ENV['MURANO_CONFIGFILE'] = @tmpdir + '/home/testcreate.config'
154
+ cfg = MrMurano::Config.new
155
+ cfg.load
156
+ cfg.set('coffee.hot', 'yes', :env)
157
+
158
+ expect(FileTest.exist?(ENV['MURANO_CONFIGFILE']))
159
+
160
+ #reload
161
+ cfg = MrMurano::Config.new
162
+ cfg.load
163
+ expect(cfg['coffee.hot']).to eq('yes')
164
+ expect(cfg.get('coffee.hot', :env)).to eq('yes')
165
+ end
166
+
167
+ it "warns about migrating old ENV name" do
168
+ ENV['MR_CONFIGFILE'] = @tmpdir + '/home/testcreate.config'
169
+ expect_any_instance_of(MrMurano::Config).to receive(:warning).once
170
+ MrMurano::Config.new
171
+ end
172
+ end
173
+
174
+ it "dumps" do
175
+ cfg = MrMurano::Config.new
176
+ cfg.load
177
+ cfg['sync.bydefault'] = 'files'
178
+ ret = cfg.dump
179
+
180
+ rawwant = IO.read(File.join(@testdir.to_path, 'spec','fixtures','dumped_config'))
181
+ template = ERB.new(rawwant)
182
+ want = template.result(binding)
183
+
184
+ expect(ret).to eq(want)
185
+ end
186
+
187
+ context "fixing permissions" do
188
+ it "fixes a directory" do
189
+ Dir.mkdir('test')
190
+ cfg = MrMurano::Config.new
191
+ cfg.fixModes(Pathname.new('test'))
192
+ if Gem.win_platform? then
193
+ expect(FileTest.world_readable? 'test').to eq(493)
194
+ expect(FileTest.world_writable? 'test').to be_nil
195
+ else
196
+ expect(FileTest.world_readable? 'test').to be_nil
197
+ expect(FileTest.world_writable? 'test').to be_nil
198
+ end
199
+ end
200
+
201
+ it "fixes a file" do
202
+ FileUtils.touch('test')
203
+ cfg = MrMurano::Config.new
204
+ cfg.fixModes(Pathname.new('test'))
205
+ if Gem.win_platform? then
206
+ expect(FileTest.world_readable? 'test').to eq(420)
207
+ expect(FileTest.world_writable? 'test').to be_nil
208
+ else
209
+ expect(FileTest.world_readable? 'test').to be_nil
210
+ expect(FileTest.world_writable? 'test').to be_nil
211
+ end
212
+ end
213
+ end
214
+ end
215
+
216
+ context "Can find the project directory by .murano/config" do
217
+ before(:example) do
218
+ @tmpdir = Dir.tmpdir
219
+ path = '/home/work/project/some/where'
220
+ @projectDir = @tmpdir + '/home/work/project'
221
+ FileUtils.mkpath(@tmpdir + path)
222
+ FileUtils.mkpath(@projectDir + '/.murano')
223
+ FileUtils.touch(@projectDir + '/.murano/config')
224
+
225
+ # Set ENV to override output of Dir.home
226
+ ENV['HOME'] = @tmpdir + '/home'
227
+ end
228
+
229
+ after(:example) do
230
+ FileUtils.remove_dir(@tmpdir + '/home', true) if FileTest.exist? @tmpdir
231
+ end
232
+
233
+ it "when in project directory" do
234
+ Dir.chdir(@projectDir) do
235
+ cfg = MrMurano::Config.new
236
+ cfg.load
237
+ # Follow symlinks to get the paths comparable.
238
+ locbase = cfg.get('location.base', :defaults).realdirpath
239
+ wkd = Pathname.new(@projectDir).realdirpath
240
+ expect(locbase).to eq(wkd)
241
+ end
242
+ end
243
+
244
+ it "when in sub directory" do
245
+ Dir.chdir(@projectDir + '/some/where') do
246
+ cfg = MrMurano::Config.new
247
+ cfg.load
248
+ # Follow symlinks to get the paths comparable.
249
+ locbase = cfg.get('location.base', :defaults).realdirpath
250
+ wkd = Pathname.new(@projectDir).realdirpath
251
+ expect(locbase).to eq(wkd)
252
+ end
253
+ end
254
+
255
+ it "when .murano is in both PWD and parent dir" do
256
+ Dir.chdir(@projectDir + '/some') do
257
+ FileUtils.mkpath('.murano')
258
+ FileUtils.touch('.murano/config')
259
+ cfg = MrMurano::Config.new
260
+ cfg.load
261
+ # Follow symlinks to get the paths comparable.
262
+ locbase = cfg.get('location.base', :defaults).realdirpath
263
+ wkd = (Pathname.new(@projectDir) + 'some').realdirpath
264
+ expect(locbase).to eq(wkd)
265
+ end
266
+ end
267
+ end
268
+
269
+ context "Can find the project directory by .murano/" do
270
+ before(:example) do
271
+ @tmpdir = Dir.tmpdir
272
+ path = '/home/work/project/some/where'
273
+ @projectDir = @tmpdir + '/home/work/project'
274
+ FileUtils.mkpath(@tmpdir + path)
275
+ FileUtils.mkpath(@projectDir + '/.murano')
276
+
277
+ # Set ENV to override output of Dir.home
278
+ ENV['HOME'] = @tmpdir + '/home'
279
+ end
280
+
281
+ after(:example) do
282
+ FileUtils.remove_dir(@tmpdir + '/home', true) if FileTest.exist? @tmpdir
283
+ end
284
+
285
+ it "when in project directory" do
286
+ Dir.chdir(@projectDir) do
287
+ cfg = MrMurano::Config.new
288
+ cfg.load
289
+ # Follow symlinks to get the paths comparable.
290
+ locbase = cfg.get('location.base', :defaults).realdirpath
291
+ wkd = Pathname.new(@projectDir).realdirpath
292
+ expect(locbase).to eq(wkd)
293
+ end
294
+ end
295
+
296
+ it "when in sub directory" do
297
+ Dir.chdir(@projectDir + '/some/where') do
298
+ cfg = MrMurano::Config.new
299
+ cfg.load
300
+ # Follow symlinks to get the paths comparable.
301
+ locbase = cfg.get('location.base', :defaults).realdirpath
302
+ wkd = Pathname.new(@projectDir).realdirpath
303
+ expect(locbase).to eq(wkd)
304
+ end
305
+ end
306
+
307
+ it "when .murano is in both PWD and parent dir" do
308
+ Dir.chdir(@projectDir + '/some') do
309
+ FileUtils.mkpath('.murano')
310
+ cfg = MrMurano::Config.new
311
+ cfg.load
312
+ # Follow symlinks to get the paths comparable.
313
+ locbase = cfg.get('location.base', :defaults).realdirpath
314
+ wkd = (Pathname.new(@projectDir) + 'some').realdirpath
315
+ expect(locbase).to eq(wkd)
316
+ end
317
+ end
318
+ end
319
+
320
+ context "When pwd is $HOME:" do
321
+ before(:example) do
322
+ @tmpdir = Dir.tmpdir
323
+ @projectDir = @tmpdir + '/home/work/project'
324
+ FileUtils.mkpath(@projectDir)
325
+ # Set ENV to override output of Dir.home
326
+ ENV['HOME'] = @tmpdir + '/home'
327
+ end
328
+
329
+ after(:example) do
330
+ FileUtils.remove_dir(@tmpdir + '/home', true) if FileTest.exist? @tmpdir
331
+ end
332
+
333
+ it "Sets a user value" do
334
+ Dir.chdir(ENV['HOME']) do
335
+ cfg = MrMurano::Config.new
336
+ cfg.load
337
+
338
+ cfg.set('bob.test', 'twelve', :user)
339
+
340
+ expect(cfg['bob.test']).to eq('twelve')
341
+ expect(cfg.get('bob.test', :user)).to eq('twelve')
342
+
343
+ expect(FileTest.exist?(ENV['HOME'] + '/.murano/config')).to be true
344
+
345
+ #reload
346
+ cfg = MrMurano::Config.new
347
+ cfg.load
348
+ expect(cfg.get('bob.test', :user)).to eq('twelve')
349
+ end
350
+ end
351
+
352
+ it "Sets project values" do # This should write
353
+ Dir.chdir(ENV['HOME']) do
354
+ cfg = MrMurano::Config.new
355
+ cfg.load
356
+
357
+ cfg.set('bob.test', 'twelve', :project)
358
+
359
+ expect(cfg['bob.test']).to eq('twelve')
360
+ expect(cfg.get('bob.test', :project)).to eq('twelve')
361
+
362
+ expect(FileTest.exist?(ENV['HOME'] + '/.murano/config')).to be true
363
+
364
+ #reload
365
+ cfg = MrMurano::Config.new
366
+ cfg.load
367
+ expect(cfg.get('bob.test', :project)).to eq('twelve')
368
+ end
369
+ end
370
+
371
+ it "write a project value and reads it as a user value" do
372
+ Dir.chdir(ENV['HOME']) do
373
+ cfg = MrMurano::Config.new
374
+ cfg.load
375
+
376
+ cfg.set('bob.test', 'twelve', :project)
377
+
378
+ expect(cfg['bob.test']).to eq('twelve')
379
+ # :user won't have the new value until it is loaded again
380
+ expect(cfg.get('bob.test', :project)).to eq('twelve')
381
+
382
+ expect(FileTest.exist?(ENV['HOME'] + '/.murano/config')).to be true
383
+
384
+ #reload
385
+ cfg = MrMurano::Config.new
386
+ cfg.load
387
+ expect(cfg.get('bob.test', :user)).to eq('twelve')
388
+ end
389
+ end
390
+ end
391
+
392
+ context "Warns about migrating old" do
393
+ include_context "WORKSPACE"
394
+
395
+ it "config file name" do
396
+ FileUtils.touch(@projectDir + '/.mrmuranorc')
397
+ expect_any_instance_of(MrMurano::Config).to receive(:warning).once
398
+ MrMurano::Config.new
399
+ end
400
+
401
+ it "config directory name" do
402
+ FileUtils.mkpath(@projectDir + '/.mrmurano')
403
+ expect_any_instance_of(MrMurano::Config).to receive(:warning).once
404
+ MrMurano::Config.new
405
+ end
406
+ end
407
+ end
408
+
409
+ # vim: set ai et sw=2 ts=2 :