MuranoCLI 2.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.
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 :