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,385 @@
1
+ require 'MrMurano/version'
2
+ require 'MrMurano/Solution-Services'
3
+ require 'tempfile'
4
+ require '_workspace'
5
+
6
+ RSpec.describe MrMurano::EventHandler do
7
+ include_context "WORKSPACE"
8
+ before(:example) do
9
+ $cfg = MrMurano::Config.new
10
+ $cfg.load
11
+ $project = MrMurano::ProjectFile.new
12
+ $project.load
13
+ $cfg['net.host'] = 'bizapi.hosted.exosite.io'
14
+ $cfg['solution.id'] = 'XYZ'
15
+
16
+ @srv = MrMurano::EventHandler.new
17
+ allow(@srv).to receive(:token).and_return("TTTTTTTTTT")
18
+ end
19
+
20
+ it "initializes" do
21
+ uri = @srv.endPoint('/')
22
+ expect(uri.to_s).to eq("https://bizapi.hosted.exosite.io/api:1/solution/XYZ/eventhandler/")
23
+ end
24
+
25
+ it "lists" do
26
+ body = {:items=>[{:id=>"9K0",
27
+ :name=>"debug",
28
+ :alias=>"XYZ_debug",
29
+ :solution_id=>"XYZ",
30
+ :service=>"device",
31
+ :event=>"datapoint",
32
+ :created_at=>"2016-07-07T19:16:19.479Z",
33
+ :updated_at=>"2016-09-12T13:26:55.868Z"}],
34
+ :total=>1}
35
+ stub_request(:get, "https://bizapi.hosted.exosite.io/api:1/solution/XYZ/eventhandler").
36
+ with(:headers=>{'Authorization'=>'token TTTTTTTTTT',
37
+ 'Content-Type'=>'application/json'}).
38
+ to_return(body: body.to_json)
39
+
40
+ ret = @srv.list()
41
+ expect(ret).to eq(body[:items])
42
+ end
43
+
44
+ it "fetches, with header" do
45
+ body = {:id=>"9K0",
46
+ :name=>"debug",
47
+ :alias=>"XYZ_debug",
48
+ :solution_id=>"XYZ",
49
+ :service=>"device",
50
+ :event=>"datapoint",
51
+ :created_at=>"2016-07-07T19:16:19.479Z",
52
+ :updated_at=>"2016-09-12T13:26:55.868Z",
53
+ :script=>%{--#EVENT device datapoint
54
+ -- lua code is here
55
+ function foo(bar)
56
+ return bar + 1
57
+ end
58
+ }
59
+ }
60
+ stub_request(:get, "https://bizapi.hosted.exosite.io/api:1/solution/XYZ/eventhandler/9K0").
61
+ with(:headers=>{'Authorization'=>'token TTTTTTTTTT',
62
+ 'Content-Type'=>'application/json'}).
63
+ to_return(body: body.to_json)
64
+
65
+ ret = @srv.fetch('9K0')
66
+ expect(ret).to eq(body[:script])
67
+ end
68
+
69
+ it "fetches, with header into block" do
70
+ body = {:id=>"9K0",
71
+ :name=>"debug",
72
+ :alias=>"XYZ_debug",
73
+ :solution_id=>"XYZ",
74
+ :service=>"device",
75
+ :event=>"datapoint",
76
+ :created_at=>"2016-07-07T19:16:19.479Z",
77
+ :updated_at=>"2016-09-12T13:26:55.868Z",
78
+ :script=>%{--#EVENT device datapoint
79
+ -- lua code is here
80
+ function foo(bar)
81
+ return bar + 1
82
+ end
83
+ }
84
+ }
85
+ stub_request(:get, "https://bizapi.hosted.exosite.io/api:1/solution/XYZ/eventhandler/9K0").
86
+ with(:headers=>{'Authorization'=>'token TTTTTTTTTT',
87
+ 'Content-Type'=>'application/json'}).
88
+ to_return(body: body.to_json)
89
+
90
+ ret = nil
91
+ @srv.fetch('9K0') { |sc| ret = sc }
92
+ expect(ret).to eq(body[:script])
93
+ end
94
+
95
+ it "fetches, without header" do
96
+ body = {:id=>"9K0",
97
+ :name=>"debug",
98
+ :alias=>"XYZ_debug",
99
+ :solution_id=>"XYZ",
100
+ :service=>"device",
101
+ :event=>"datapoint",
102
+ :created_at=>"2016-07-07T19:16:19.479Z",
103
+ :updated_at=>"2016-09-12T13:26:55.868Z",
104
+ :script=>%{-- lua code is here
105
+ function foo(bar)
106
+ return bar + 1
107
+ end
108
+ }
109
+ }
110
+ stub_request(:get, "https://bizapi.hosted.exosite.io/api:1/solution/XYZ/eventhandler/9K0").
111
+ with(:headers=>{'Authorization'=>'token TTTTTTTTTT',
112
+ 'Content-Type'=>'application/json'}).
113
+ to_return(body: body.to_json)
114
+
115
+ ret = @srv.fetch('9K0')
116
+ expect(ret).to eq(%{--#EVENT device datapoint
117
+ -- lua code is here
118
+ function foo(bar)
119
+ return bar + 1
120
+ end
121
+ })
122
+ end
123
+
124
+ it "removes" do
125
+ stub_request(:delete, "https://bizapi.hosted.exosite.io/api:1/solution/XYZ/eventhandler/9K0").
126
+ with(:headers=>{'Authorization'=>'token TTTTTTTTTT',
127
+ 'Content-Type'=>'application/json'}).
128
+ to_return(body: "")
129
+
130
+ ret = @srv.remove('9K0')
131
+ expect(ret).to eq({})
132
+ end
133
+
134
+ it "uploads over old version" do
135
+ stub_request(:put, "https://bizapi.hosted.exosite.io/api:1/solution/XYZ/eventhandler/XYZ_data_datapoint").
136
+ with(:headers=>{'Authorization'=>'token TTTTTTTTTT',
137
+ 'Content-Type'=>'application/json'}).
138
+ to_return(body: "")
139
+
140
+ Tempfile.open('foo') do |tio|
141
+ tio << %{-- lua code is here
142
+ function foo(bar)
143
+ return bar + 1
144
+ end
145
+ }
146
+ tio.close
147
+
148
+ ret = @srv.upload(tio.path, {:id=>"9K0",
149
+ :service=>'data',
150
+ :event=>'datapoint',
151
+ :solution_id=>"XYZ",
152
+ })
153
+ expect(ret)
154
+ end
155
+ end
156
+
157
+ it "uploads when nothing is there" do
158
+ stub_request(:put, "https://bizapi.hosted.exosite.io/api:1/solution/XYZ/eventhandler/XYZ_device_datapoint").
159
+ with(:headers=>{'Authorization'=>'token TTTTTTTTTT',
160
+ 'Content-Type'=>'application/json'}).
161
+ to_return(status: 404)
162
+ stub_request(:post, "https://bizapi.hosted.exosite.io/api:1/solution/XYZ/eventhandler/").
163
+ with(:headers=>{'Authorization'=>'token TTTTTTTTTT',
164
+ 'Content-Type'=>'application/json'}).
165
+ to_return(body: "")
166
+
167
+ Tempfile.open('foo') do |tio|
168
+ tio << %{-- lua code is here
169
+ function foo(bar)
170
+ return bar + 1
171
+ end
172
+ }
173
+ tio.close
174
+
175
+ ret = @srv.upload(tio.path, {:id=>"9K0",
176
+ :solution_id=>"XYZ",
177
+ :service=>"device",
178
+ :event=>"datapoint",
179
+ })
180
+ expect(ret)
181
+ end
182
+
183
+ end
184
+
185
+ context "compares" do
186
+ before(:example) do
187
+ @iA = {:id=>"9K0",
188
+ :name=>"debug",
189
+ :alias=>"XYZ_debug",
190
+ :solution_id=>"XYZ",
191
+ :service=>"device",
192
+ :event=>"datapoint",
193
+ :created_at=>"2016-07-07T19:16:19.479Z",
194
+ :updated_at=>"2016-09-12T13:26:55.868Z"}
195
+ @iB = {:id=>"9K0",
196
+ :name=>"debug",
197
+ :alias=>"XYZ_debug",
198
+ :solution_id=>"XYZ",
199
+ :service=>"device",
200
+ :event=>"datapoint",
201
+ :created_at=>"2016-07-07T19:16:19.479Z",
202
+ :updated_at=>"2016-09-12T13:26:55.868Z"}
203
+ end
204
+ it "both have updated_at" do
205
+ ret = @srv.docmp(@iA, @iB)
206
+ expect(ret).to eq(false)
207
+ end
208
+
209
+ it "iA is a local file" do
210
+ Tempfile.open('foo') do |tio|
211
+ tio << "something"
212
+ tio.close
213
+ iA = @iA.reject{|k,v| k == :updated_at}.merge({
214
+ :local_path => Pathname.new(tio.path)
215
+ })
216
+ ret = @srv.docmp(iA, @iB)
217
+ expect(ret).to eq(true)
218
+
219
+ iB = @iB.merge({:updated_at=>Pathname.new(tio.path).mtime.getutc})
220
+ ret = @srv.docmp(iA, iB)
221
+ expect(ret).to eq(false)
222
+ end
223
+ end
224
+
225
+ it "iB is a local file" do
226
+ Tempfile.open('foo') do |tio|
227
+ tio << "something"
228
+ tio.close
229
+ iB = @iB.reject{|k,v| k == :updated_at}.merge({
230
+ :local_path => Pathname.new(tio.path)
231
+ })
232
+ ret = @srv.docmp(@iA, iB)
233
+ expect(ret).to eq(true)
234
+
235
+ iA = @iA.merge({:updated_at=>Pathname.new(tio.path).mtime.getutc})
236
+ ret = @srv.docmp(iA, iB)
237
+ expect(ret).to eq(false)
238
+ end
239
+ end
240
+ end
241
+
242
+ context "Lookup functions" do
243
+ it "gets local name" do
244
+ ret = @srv.tolocalname({ :name=>"bob" }, nil)
245
+ expect(ret).to eq('bob.lua')
246
+ end
247
+
248
+ it "gets synckey" do
249
+ ret = @srv.synckey({ :service=>'device', :event=>'datapoint' })
250
+ expect(ret).to eq("device_datapoint")
251
+ end
252
+
253
+ it "gets searchfor" do
254
+ $cfg['eventhandler.searchFor'] = %{a b c/**/d/*.bob}
255
+ ret = @srv.searchFor
256
+ expect(ret).to eq(["a", "b", "c/**/d/*.bob"])
257
+ end
258
+
259
+ it "gets ignoring" do
260
+ $cfg['eventhandler.ignoring'] = %{a b c/**/d/*.bob}
261
+ ret = @srv.ignoring
262
+ expect(ret).to eq(["a", "b", "c/**/d/*.bob"])
263
+ end
264
+
265
+ it "raises on alias without service" do
266
+ expect {
267
+ @srv.mkname( {:event=>'bob'} )
268
+ }.to raise_error %{Missing parts! {"event":"bob"}}
269
+ end
270
+
271
+ it "raises on alias without event" do
272
+ expect {
273
+ @srv.mkalias( {:service=>'bob'} )
274
+ }.to raise_error %{Missing parts! {"service":"bob"}}
275
+ end
276
+
277
+ it "raises on name without service" do
278
+ expect {
279
+ @srv.mkalias( {:event=>'bob'} )
280
+ }.to raise_error %{Missing parts! {"event":"bob"}}
281
+ end
282
+
283
+ it "raises on name without event" do
284
+ expect {
285
+ @srv.mkname( {:service=>'bob'} )
286
+ }.to raise_error %{Missing parts! {"service":"bob"}}
287
+ end
288
+ end
289
+
290
+ context "toRemoteItem" do
291
+ before(:example) do
292
+ allow(@srv).to receive(:warning)
293
+ end
294
+
295
+ it "reads one" do
296
+ Tempfile.open('foo') do |tio|
297
+ tio << %{--#EVENT device datapoint
298
+ -- do something.
299
+ Tsdb.write{tags={sn='1'},metrics={[data.alias]=data.value[2]}}
300
+ }.gsub(/^\s+/,'')
301
+ tio.close
302
+
303
+ ret = @srv.toRemoteItem(nil, tio.path)
304
+ expect(ret).to eq({:service=>'device',
305
+ :event=>'datapoint',
306
+ :line=>0,
307
+ :line_end=>3,
308
+ :local_path=>Pathname.new(tio.path),
309
+ :script=>%{--#EVENT device datapoint\n-- do something.\nTsdb.write{tags={sn='1'},metrics={[data.alias]=data.value[2]}}\n},
310
+ })
311
+ end
312
+ end
313
+
314
+ it "skips all when no header found" do
315
+ Tempfile.open('foo') do |tio|
316
+ tio << %{
317
+ -- do something.
318
+ Tsdb.write{tags={sn='1'},metrics={[data.alias]=data.value[2]}}
319
+ }.gsub(/^\s+/,'')
320
+ tio.close
321
+
322
+ ret = @srv.toRemoteItem(nil, tio.path)
323
+ expect(ret).to eq(nil)
324
+ end
325
+ end
326
+
327
+ it "skips junk at begining" do
328
+ Tempfile.open('foo') do |tio|
329
+ tio << %{
330
+ -- do something.
331
+ --#EVENT device datapoint
332
+ Tsdb.write{tags={sn='1'},metrics={[data.alias]=data.value[2]}}
333
+ }.gsub(/^\s+/,'')
334
+ tio.close
335
+
336
+ ret = @srv.toRemoteItem(nil, tio.path)
337
+ expect(ret).to eq({:service=>'device',
338
+ :event=>'datapoint',
339
+ :line=>1,
340
+ :line_end=>3,
341
+ :local_path=>Pathname.new(tio.path),
342
+ :script=>%{--#EVENT device datapoint\nTsdb.write{tags={sn='1'},metrics={[data.alias]=data.value[2]}}\n},
343
+ })
344
+ end
345
+ end
346
+
347
+ end
348
+
349
+ context "Matching" do
350
+ before(:example) do
351
+ @an_item = {
352
+ :service=>'bob',
353
+ :event=>'built',
354
+ :local_path=>Pathname.new('a/relative/path.lua'),
355
+ }
356
+ end
357
+ context "service" do
358
+ it "any event" do
359
+ ret = @srv.match(@an_item, '#bob#')
360
+ expect(ret).to be true
361
+ ret = @srv.match(@an_item, '#email#')
362
+ expect(ret).to be false
363
+ end
364
+ it "exact event" do
365
+ ret = @srv.match(@an_item, '#bob#built')
366
+ expect(ret).to be true
367
+ ret = @srv.match(@an_item, '#email#built')
368
+ expect(ret).to be false
369
+ end
370
+ end
371
+ context "any service" do
372
+ it "any event" do
373
+ ret = @srv.match(@an_item, '##')
374
+ expect(ret).to be true
375
+ end
376
+ it "exact event" do
377
+ ret = @srv.match(@an_item, '##built')
378
+ expect(ret).to be true
379
+ ret = @srv.match(@an_item, '##sent')
380
+ expect(ret).to be false
381
+ end
382
+ end
383
+ end
384
+ end
385
+ # vim: set ai et sw=2 ts=2 :
@@ -0,0 +1,465 @@
1
+ require 'MrMurano/version'
2
+ require 'MrMurano/Solution-Services'
3
+ require 'tempfile'
4
+ require '_workspace'
5
+
6
+ RSpec.describe MrMurano::Library do
7
+ include_context "WORKSPACE"
8
+ before(:example) do
9
+ $cfg = MrMurano::Config.new
10
+ $cfg.load
11
+ $project = MrMurano::ProjectFile.new
12
+ $project.load
13
+ $cfg['net.host'] = 'bizapi.hosted.exosite.io'
14
+ $cfg['solution.id'] = 'XYZ'
15
+
16
+ @srv = MrMurano::Library.new
17
+ allow(@srv).to receive(:token).and_return("TTTTTTTTTT")
18
+ end
19
+
20
+ it "initializes" do
21
+ uri = @srv.endPoint('/')
22
+ expect(uri.to_s).to eq("https://bizapi.hosted.exosite.io/api:1/solution/XYZ/library/")
23
+ end
24
+
25
+ it "lists" do
26
+ body = {:items=>[{:id=>"9K0",
27
+ :name=>"debug",
28
+ :alias=>"XYZ_debug",
29
+ :solution_id=>"XYZ",
30
+ :created_at=>"2016-07-07T19:16:19.479Z",
31
+ :updated_at=>"2016-09-12T13:26:55.868Z"}],
32
+ :total=>1}
33
+ stub_request(:get, "https://bizapi.hosted.exosite.io/api:1/solution/XYZ/library").
34
+ with(:headers=>{'Authorization'=>'token TTTTTTTTTT',
35
+ 'Content-Type'=>'application/json'}).
36
+ to_return(body: body.to_json)
37
+
38
+ ret = @srv.list()
39
+ expect(ret).to eq(body[:items])
40
+ end
41
+
42
+ context "fetching" do
43
+ it "fetches" do
44
+ body = {:id=>"9K0",
45
+ :name=>"debug",
46
+ :alias=>"XYZ_debug",
47
+ :solution_id=>"XYZ",
48
+ :created_at=>"2016-07-07T19:16:19.479Z",
49
+ :updated_at=>"2016-09-12T13:26:55.868Z",
50
+ :script=>%{-- lua code is here
51
+ function foo(bar)
52
+ return bar + 1
53
+ end
54
+ }
55
+ }
56
+ stub_request(:get, "https://bizapi.hosted.exosite.io/api:1/solution/XYZ/library/9K0").
57
+ with(:headers=>{'Authorization'=>'token TTTTTTTTTT',
58
+ 'Content-Type'=>'application/json'}).
59
+ to_return(body: body.to_json)
60
+
61
+ ret = @srv.fetch('9K0')
62
+ expect(ret).to eq(body[:script])
63
+ end
64
+
65
+ it "fetches with block" do
66
+ body = {:id=>"9K0",
67
+ :name=>"debug",
68
+ :alias=>"XYZ_debug",
69
+ :solution_id=>"XYZ",
70
+ :created_at=>"2016-07-07T19:16:19.479Z",
71
+ :updated_at=>"2016-09-12T13:26:55.868Z",
72
+ :script=>%{-- lua code is here
73
+ function foo(bar)
74
+ return bar + 1
75
+ end
76
+ }
77
+ }
78
+ stub_request(:get, "https://bizapi.hosted.exosite.io/api:1/solution/XYZ/library/9K0").
79
+ with(:headers=>{'Authorization'=>'token TTTTTTTTTT',
80
+ 'Content-Type'=>'application/json'}).
81
+ to_return(body: body.to_json)
82
+
83
+ ret = nil
84
+ @srv.fetch('9K0') {|sc| ret = sc}
85
+ expect(ret).to eq(body[:script])
86
+ end
87
+
88
+ it "Returns empty if script missing" do
89
+ body = {:id=>"9K0",
90
+ :name=>"debug",
91
+ :alias=>"XYZ_debug",
92
+ :solution_id=>"XYZ",
93
+ :created_at=>"2016-07-07T19:16:19.479Z",
94
+ :updated_at=>"2016-09-12T13:26:55.868Z",
95
+ }
96
+ stub_request(:get, "https://bizapi.hosted.exosite.io/api:1/solution/XYZ/library/9K0").
97
+ with(:headers=>{'Authorization'=>'token TTTTTTTTTT',
98
+ 'Content-Type'=>'application/json'}).
99
+ to_return(body: body.to_json)
100
+
101
+ ret = @srv.fetch('9K0')
102
+ expect(ret).to eq('')
103
+ end
104
+
105
+ it "Displays error if wrong result type" do
106
+ stub_request(:get, "https://bizapi.hosted.exosite.io/api:1/solution/XYZ/library/9K0").
107
+ with(:headers=>{'Authorization'=>'token TTTTTTTTTT',
108
+ 'Content-Type'=>'application/json'}).
109
+ to_return(body: "this isn't what we expected")
110
+
111
+ saved = $stderr
112
+ $stderr = StringIO.new
113
+ ret = @srv.fetch('9K0')
114
+ expect(ret).to eq('')
115
+ expect($stderr.string).to eq(%{\e[31mUnexpected result type, assuming empty instead: this isn't what we expected\e[0m\n})
116
+ $stderr = saved
117
+ end
118
+ end
119
+
120
+ it "removes" do
121
+ stub_request(:delete, "https://bizapi.hosted.exosite.io/api:1/solution/XYZ/library/9K0").
122
+ with(:headers=>{'Authorization'=>'token TTTTTTTTTT',
123
+ 'Content-Type'=>'application/json'}).
124
+ to_return(body: "")
125
+
126
+ ret = @srv.remove('9K0')
127
+ expect(ret).to eq({})
128
+ end
129
+
130
+ context "uploads" do
131
+ it "over old version" do
132
+ stub_request(:put, "https://bizapi.hosted.exosite.io/api:1/solution/XYZ/library/XYZ_debug").
133
+ with(:headers=>{'Authorization'=>'token TTTTTTTTTT',
134
+ 'Content-Type'=>'application/json'}).
135
+ to_return(body: "")
136
+
137
+ Tempfile.open('foo') do |tio|
138
+ tio << %{-- lua code is here
139
+ function foo(bar)
140
+ return bar + 1
141
+ end
142
+ }
143
+ tio.close
144
+
145
+ ret = @srv.upload(tio.path, {:id=>"9K0",
146
+ :name=>"debug",
147
+ :alias=>"XYZ_debug",
148
+ :solution_id=>"XYZ",
149
+ })
150
+ expect(ret)
151
+ end
152
+ end
153
+
154
+ it "when nothing is there" do
155
+ stub_request(:put, "https://bizapi.hosted.exosite.io/api:1/solution/XYZ/library/XYZ_debug").
156
+ with(:headers=>{'Authorization'=>'token TTTTTTTTTT',
157
+ 'Content-Type'=>'application/json'}).
158
+ to_return(status: 404)
159
+ stub_request(:post, "https://bizapi.hosted.exosite.io/api:1/solution/XYZ/library/").
160
+ with(:headers=>{'Authorization'=>'token TTTTTTTTTT',
161
+ 'Content-Type'=>'application/json'}).
162
+ to_return(body: "")
163
+
164
+ Tempfile.open('foo') do |tio|
165
+ tio << %{-- lua code is here
166
+ function foo(bar)
167
+ return bar + 1
168
+ end
169
+ }
170
+ tio.close
171
+
172
+ ret = @srv.upload(tio.path, {:id=>"9K0",
173
+ :name=>"debug",
174
+ :alias=>"XYZ_debug",
175
+ :solution_id=>"XYZ",
176
+ })
177
+ expect(ret)
178
+ end
179
+ end
180
+
181
+ it "shows other errors" do
182
+ stub_request(:put, "https://bizapi.hosted.exosite.io/api:1/solution/XYZ/library/XYZ_debug").
183
+ with(:headers=>{'Authorization'=>'token TTTTTTTTTT',
184
+ 'Content-Type'=>'application/json'}).
185
+ to_return(status: 418, body: %{{"teapot":true}})
186
+
187
+ Tempfile.open('foo') do |tio|
188
+ tio << %{-- lua code is here
189
+ function foo(bar)
190
+ return bar + 1
191
+ end
192
+ }
193
+ tio.close
194
+
195
+ expect(@srv).to receive(:error).and_return(nil)
196
+ ret = @srv.upload(tio.path, {:id=>"9K0",
197
+ :name=>"debug",
198
+ :alias=>"XYZ_debug",
199
+ :solution_id=>"XYZ",
200
+ })
201
+ expect(ret)
202
+ end
203
+ end
204
+
205
+ it "over old version; replacing cache miss" do
206
+ stub_request(:put, "https://bizapi.hosted.exosite.io/api:1/solution/XYZ/library/XYZ_debug").
207
+ with(:headers=>{'Authorization'=>'token TTTTTTTTTT',
208
+ 'Content-Type'=>'application/json'}).
209
+ to_return(body: "")
210
+
211
+ Tempfile.open('foo') do |tio|
212
+ tio << %{-- lua code is here
213
+ function foo(bar)
214
+ return bar + 1
215
+ end
216
+ }
217
+ tio.close
218
+
219
+ cacheFile = $cfg.file_at(@srv.cacheFileName)
220
+ FileUtils.touch(cacheFile.to_path)
221
+ ret = @srv.upload(tio.path, {:id=>"9K0",
222
+ :name=>"debug",
223
+ :alias=>"XYZ_debug",
224
+ :solution_id=>"XYZ",
225
+ })
226
+ expect(ret)
227
+ end
228
+ end
229
+
230
+ it "over old version; replacing cache hit" do
231
+ stub_request(:put, "https://bizapi.hosted.exosite.io/api:1/solution/XYZ/library/XYZ_debug").
232
+ with(:headers=>{'Authorization'=>'token TTTTTTTTTT',
233
+ 'Content-Type'=>'application/json'}).
234
+ to_return(body: "")
235
+
236
+ Tempfile.open('foo') do |tio|
237
+ tio << %{-- lua code is here
238
+ function foo(bar)
239
+ return bar + 1
240
+ end
241
+ }
242
+ tio.close
243
+
244
+ cacheFile = $cfg.file_at(@srv.cacheFileName)
245
+ cacheFile.open('w') do |cfio|
246
+ cfio << {tio.path=>{:sha1=>"6",
247
+ :updated_at=>Time.now.getutc.to_datetime.iso8601(3)}
248
+ }.to_yaml
249
+ end
250
+ ret = @srv.upload(tio.path, {:id=>"9K0",
251
+ :name=>"debug",
252
+ :alias=>"XYZ_debug",
253
+ :solution_id=>"XYZ",
254
+ })
255
+ expect(ret)
256
+ end
257
+ end
258
+ end
259
+
260
+ context "compares" do
261
+ before(:example) do
262
+ @iA = {:id=>"9K0",
263
+ :name=>"debug",
264
+ :alias=>"XYZ_debug",
265
+ :solution_id=>"XYZ",
266
+ :created_at=>"2016-07-07T19:16:19.479Z",
267
+ :updated_at=>"2016-09-12T13:26:55.868Z"}
268
+ @iB = {:id=>"9K0",
269
+ :name=>"debug",
270
+ :alias=>"XYZ_debug",
271
+ :solution_id=>"XYZ",
272
+ :created_at=>"2016-07-07T19:16:19.479Z",
273
+ :updated_at=>"2016-09-12T13:26:55.868Z"}
274
+ end
275
+ it "both have updated_at" do
276
+ ret = @srv.docmp(@iA, @iB)
277
+ expect(ret).to eq(false)
278
+ end
279
+
280
+ context "iA is a local file" do
281
+ it "no cacheFile" do
282
+ Tempfile.open('foo') do |tio|
283
+ tio << "something"
284
+ tio.close
285
+ iA = @iA.reject{|k,v| k == :updated_at}.merge({
286
+ :local_path => Pathname.new(tio.path)
287
+ })
288
+ ret = @srv.docmp(iA, @iB)
289
+ expect(ret).to eq(true)
290
+
291
+ iB = @iB.merge({:updated_at=>Pathname.new(tio.path).mtime.getutc})
292
+ ret = @srv.docmp(iA, iB)
293
+ expect(ret).to eq(false)
294
+ end
295
+ end
296
+
297
+ it "cache miss" do
298
+ cacheFile = $cfg.file_at(@srv.cacheFileName)
299
+ FileUtils.touch(cacheFile.to_path)
300
+ Tempfile.open('foo') do |tio|
301
+ tio << "something"
302
+ tio.close
303
+ iA = @iA.reject{|k,v| k == :updated_at}.merge({
304
+ :local_path => Pathname.new(tio.path)
305
+ })
306
+ ret = @srv.docmp(iA, @iB)
307
+ expect(ret).to eq(true)
308
+
309
+ iB = @iB.merge({:updated_at=>Pathname.new(tio.path).mtime.getutc})
310
+ ret = @srv.docmp(iA, iB)
311
+ expect(ret).to eq(false)
312
+ end
313
+ end
314
+
315
+ it "cache hit" do
316
+ cacheFile = $cfg.file_at(@srv.cacheFileName)
317
+ Tempfile.open('foo') do |tio|
318
+ tio << "something"
319
+ tio.close
320
+ tio_mtime = Pathname.new(tio.path).mtime.getutc
321
+ entry = {
322
+ :sha1=>Digest::SHA1.file(tio.path).hexdigest,
323
+ :updated_at=>tio_mtime.to_datetime.iso8601(3)
324
+ }
325
+ cacheFile.open('w') do |io|
326
+ cache = {}
327
+ cache[tio.path] = entry
328
+ io << cache.to_yaml
329
+ end
330
+
331
+ iA = @iA.reject{|k,v| k == :updated_at}.merge({
332
+ :local_path => Pathname.new(tio.path)
333
+ })
334
+ ret = @srv.docmp(iA, @iB)
335
+ expect(ret).to eq(true)
336
+
337
+ iB = @iB.merge({:updated_at=>tio_mtime})
338
+ ret = @srv.docmp(iA, iB)
339
+ expect(ret).to eq(false)
340
+ end
341
+ end
342
+ end
343
+
344
+ context "iB is a local file" do
345
+ it "no cacheFile" do
346
+ Tempfile.open('foo') do |tio|
347
+ tio << "something"
348
+ tio.close
349
+ iB = @iB.reject{|k,v| k == :updated_at}.merge({
350
+ :local_path => Pathname.new(tio.path)
351
+ })
352
+ ret = @srv.docmp(@iA, iB)
353
+ expect(ret).to eq(true)
354
+
355
+ iA = @iA.merge({:updated_at=>Pathname.new(tio.path).mtime.getutc})
356
+ ret = @srv.docmp(iA, iB)
357
+ expect(ret).to eq(false)
358
+ end
359
+ end
360
+
361
+ it "cache miss" do
362
+ cacheFile = $cfg.file_at(@srv.cacheFileName)
363
+ FileUtils.touch(cacheFile.to_path)
364
+ Tempfile.open('foo') do |tio|
365
+ tio << "something"
366
+ tio.close
367
+ iB = @iB.reject{|k,v| k == :updated_at}.merge({
368
+ :local_path => Pathname.new(tio.path)
369
+ })
370
+ ret = @srv.docmp(@iA, iB)
371
+ expect(ret).to eq(true)
372
+
373
+ iA = @iA.merge({:updated_at=>Pathname.new(tio.path).mtime.getutc})
374
+ ret = @srv.docmp(iA, iB)
375
+ expect(ret).to eq(false)
376
+ end
377
+ end
378
+
379
+ it "cache hit" do
380
+ cacheFile = $cfg.file_at(@srv.cacheFileName)
381
+ Tempfile.open('foo') do |tio|
382
+ tio << "something"
383
+ tio.close
384
+ tio_mtime = Pathname.new(tio.path).mtime.getutc
385
+ entry = {
386
+ :sha1=>Digest::SHA1.file(tio.path).hexdigest,
387
+ :updated_at=>tio_mtime.to_datetime.iso8601(3)
388
+ }
389
+ cacheFile.open('w') do |io|
390
+ cache = {}
391
+ cache[tio.path] = entry
392
+ io << cache.to_yaml
393
+ end
394
+
395
+ iB = @iB.reject{|k,v| k == :updated_at}.merge({
396
+ :local_path => Pathname.new(tio.path)
397
+ })
398
+ ret = @srv.docmp(@iA, iB)
399
+ expect(ret).to eq(true)
400
+
401
+ iA = @iA.merge({:updated_at=>tio_mtime})
402
+ ret = @srv.docmp(iA, iB)
403
+ expect(ret).to eq(false)
404
+ end
405
+ end
406
+ end
407
+ end
408
+
409
+ context "Lookup functions" do
410
+ it "gets local name" do
411
+ ret = @srv.tolocalname({ :name=>"bob" }, nil)
412
+ expect(ret).to eq('bob.lua')
413
+ end
414
+
415
+ it "gets synckey" do
416
+ ret = @srv.synckey({ :name=>'device' })
417
+ expect(ret).to eq("device")
418
+ end
419
+
420
+ it "gets searchfor" do
421
+ $cfg['modules.searchFor'] = %{a b c/**/d/*.bob}
422
+ ret = @srv.searchFor
423
+ expect(ret).to eq(["a", "b", "c/**/d/*.bob"])
424
+ end
425
+
426
+ it "gets ignoring" do
427
+ $cfg['modules.ignoring'] = %{a b c/**/d/*.bob}
428
+ ret = @srv.ignoring
429
+ expect(ret).to eq(["a", "b", "c/**/d/*.bob"])
430
+ end
431
+
432
+ it "raises on alias without service" do
433
+ expect {
434
+ @srv.mkname( {:event=>'bob'} )
435
+ }.to raise_error %{Missing parts! {"event":"bob"}}
436
+ end
437
+
438
+ it "raises on alias without event" do
439
+ expect {
440
+ @srv.mkalias( {:service=>'bob'} )
441
+ }.to raise_error %{Missing parts! {"service":"bob"}}
442
+ end
443
+
444
+ it "raises on name without service" do
445
+ expect {
446
+ @srv.mkalias( {:event=>'bob'} )
447
+ }.to raise_error %{Missing parts! {"event":"bob"}}
448
+ end
449
+
450
+ it "raises on name without event" do
451
+ expect {
452
+ @srv.mkname( {:service=>'bob'} )
453
+ }.to raise_error %{Missing parts! {"service":"bob"}}
454
+ end
455
+ end
456
+
457
+ context "toRemoteItem" do
458
+ it "reads one" do
459
+ path = Pathname.new(@projectDir) + 'test.lua'
460
+ ret = @srv.toRemoteItem(nil, path)
461
+ expect(ret).to eq({:name=>'test'})
462
+ end
463
+ end
464
+ end
465
+ # vim: set ai et sw=2 ts=2 :