Merge lp:~benji/juju-gui/bug-1103477 into lp:juju-gui/experimental
- bug-1103477
- Merge into trunk
Status: | Merged | ||||
---|---|---|---|---|---|
Merged at revision: | 345 | ||||
Proposed branch: | lp:~benji/juju-gui/bug-1103477 | ||||
Merge into: | lp:juju-gui/experimental | ||||
Diff against target: |
374 lines (+92/-68) 6 files modified
app/store/env.js (+13/-10) app/views/service.js (+2/-2) app/views/topology/relation.js (+9/-14) test/test_application_notifications.js (+24/-34) test/test_env.js (+9/-6) test/test_topology_relation.js (+35/-2) |
||||
To merge this branch: | bzr merge lp:~benji/juju-gui/bug-1103477 | ||||
Related bugs: |
|
Reviewer | Review Type | Date Requested | Status |
---|---|---|---|
Juju GUI Hackers | Pending | ||
Review via email: mp+144594@code.launchpad.net |
Commit message
Description of the change
Add a test for the fix for bug 1103204
This branch also includes some refactoring of where relation names are
calculated in an effort to DRY it up as well as make testing a tad easier.
Madison Scott-Clary (makyo) wrote : | # |
Gary Poster (gary) wrote : | # |
Land with changes.
Extremely nice branch, Benji. Thank you.
Gary
https:/
File app/views/
https:/
app/views/
I expected you to change this "d" argument to "relation" like your other
nice changes. Would be nice. :-)
https:/
File app/views/utils.js (right):
https:/
app/views/
data.
typo: derived
- 346. By Benji York
-
merge from trunk
- 347. By Benji York
-
give a parameter a better name
Preview Diff
1 | === modified file 'app/store/env.js' |
2 | --- app/store/env.js 2013-01-24 14:14:45 +0000 |
3 | +++ app/store/env.js 2013-01-24 19:23:21 +0000 |
4 | @@ -13,6 +13,9 @@ |
5 | Environment.superclass.constructor.apply(this, arguments); |
6 | } |
7 | |
8 | + var endpointToName = function(endpoint) { |
9 | + return endpoint[0] + ':' + endpoint[1].name; |
10 | + }; |
11 | |
12 | Environment.NAME = 'env'; |
13 | Environment.ATTRS = { |
14 | @@ -204,19 +207,19 @@ |
15 | * Add a relation between two services. |
16 | * |
17 | * @method add_relation |
18 | - * @param {String} endpoint_a A string `service:interface` representing |
19 | + * @param {Object} endpointA An array of [service, interface] representing |
20 | the first endpoint to connect. |
21 | - * @param {String} endpoint_b A string `service:interface` representing |
22 | + * @param {Object} endpointB An array of [service, interface] representing |
23 | the second endpoint to connect. |
24 | * @param {Function} callback A callable that must be called once the |
25 | operation is performed. |
26 | * @return {undefined} Sends a message to the server only. |
27 | */ |
28 | - add_relation: function(endpoint_a, endpoint_b, callback) { |
29 | + add_relation: function(endpointA, endpointB, callback) { |
30 | this._send_rpc({ |
31 | 'op': 'add_relation', |
32 | - 'endpoint_a': endpoint_a, |
33 | - 'endpoint_b': endpoint_b}, callback, true); |
34 | + 'endpoint_a': endpointToName(endpointA), |
35 | + 'endpoint_b': endpointToName(endpointB)}, callback, true); |
36 | }, |
37 | |
38 | get_charm: function(charm_url, callback) { |
39 | @@ -311,19 +314,19 @@ |
40 | * Remove a relation between two services. |
41 | * |
42 | * @method remove_relation |
43 | - * @param {String} endpoint_a A string `service:interface` representing |
44 | + * @param {Object} endpointA An array of [service, interface] representing |
45 | the first endpoint to disconnect. |
46 | - * @param {String} endpoint_b A string `service:interface` representing |
47 | + * @param {Object} endpointB An array of [service, interface] representing |
48 | the second endpoint to disconnect. |
49 | * @param {Function} callback A callable that must be called once the |
50 | operation is performed. |
51 | * @return {undefined} Sends a message to the server only. |
52 | */ |
53 | - remove_relation: function(endpoint_a, endpoint_b, callback) { |
54 | + remove_relation: function(endpointA, endpointB, callback) { |
55 | this._send_rpc({ |
56 | 'op': 'remove_relation', |
57 | - 'endpoint_a': endpoint_a, |
58 | - 'endpoint_b': endpoint_b}, callback, true); |
59 | + 'endpoint_a': endpointToName(endpointA), |
60 | + 'endpoint_b': endpointToName(endpointB)}, callback, true); |
61 | }, |
62 | |
63 | /** |
64 | |
65 | === modified file 'app/views/service.js' |
66 | --- app/views/service.js 2013-01-24 14:14:45 +0000 |
67 | +++ app/views/service.js 2013-01-24 19:23:21 +0000 |
68 | @@ -445,14 +445,14 @@ |
69 | service = this.get('model'), |
70 | relation = db.relations.getById(rel_id), |
71 | endpoints = relation.get('endpoints'), |
72 | - endpoint_a = endpoints[0][0] + ':' + endpoints[0][1].name, |
73 | + endpoint_a = endpoints[0], |
74 | endpoint_b; |
75 | |
76 | if (endpoints.length === 1) { |
77 | // For a peer relationship, both endpoints are the same. |
78 | endpoint_b = endpoint_a; |
79 | } else { |
80 | - endpoint_b = endpoints[1][0] + ':' + endpoints[1][1].name; |
81 | + endpoint_b = endpoints[1]; |
82 | } |
83 | |
84 | ev.target.set('disabled', true); |
85 | |
86 | === modified file 'app/views/topology/relation.js' |
87 | --- app/views/topology/relation.js 2013-01-24 19:02:40 +0000 |
88 | +++ app/views/topology/relation.js 2013-01-24 19:23:21 +0000 |
89 | @@ -445,19 +445,16 @@ |
90 | self.addRelation(); // Will clear the state. |
91 | } |
92 | }, |
93 | - removeRelation: function(d, view, confirmButton) { |
94 | + removeRelation: function(relation, view, confirmButton) { |
95 | var env = this.get('component').get('env'); |
96 | - var endpoints = d.endpoints; |
97 | - var relationId = d.relation_id; |
98 | // At this time, relations may have been redrawn, so here we have to |
99 | // retrieve the relation DOM element again. |
100 | - var relationElement = view.get('container').one('#' + relationId); |
101 | + var relationElement = view.get('container') |
102 | + .one('#' + relation.relation_id); |
103 | utils.addSVGClass(relationElement, 'to-remove pending-relation'); |
104 | - env.remove_relation( |
105 | - endpoints[0][0] + ':' + endpoints[0][1].name, |
106 | - endpoints[1][0] + ':' + endpoints[1][1].name, |
107 | + env.remove_relation(relation.endpoints[0], relation.endpoints[1], |
108 | Y.bind(this._removeRelationCallback, this, view, |
109 | - relationElement, relationId, confirmButton)); |
110 | + relationElement, relation.relation_id, confirmButton)); |
111 | }, |
112 | |
113 | _removeRelationCallback: function(view, |
114 | @@ -722,9 +719,7 @@ |
115 | |
116 | // Fire event to add relation in juju. |
117 | // This needs to specify interface in the future. |
118 | - env.add_relation( |
119 | - endpoints[0][0] + ':' + endpoints[0][1].name, |
120 | - endpoints[1][0] + ':' + endpoints[1][1].name, |
121 | + env.add_relation(endpoints[0], endpoints[1], |
122 | Y.bind(this._addRelationCallback, this, view, relation_id) |
123 | ); |
124 | view.set('currentServiceClickAction', 'hideServiceMenu'); |
125 | @@ -838,8 +833,8 @@ |
126 | 'active'); |
127 | }, |
128 | |
129 | - relationClick: function(d, self) { |
130 | - if (d.isSubordinate) { |
131 | + relationClick: function(relation self) { |
132 | + if (relation.isSubordinate) { |
133 | var subRelDialog = views.createModalPanel( |
134 | 'You may not remove a subordinate relation.', |
135 | '#rmsubrelation-modal-panel'); |
136 | @@ -861,7 +856,7 @@ |
137 | subRelDialog.get('boundingBox').all('.yui3-button') |
138 | .removeClass('yui3-button'); |
139 | } else { |
140 | - self.removeRelationConfirm(d, this, self); |
141 | + self.removeRelationConfirm(relation, this, self); |
142 | } |
143 | } |
144 | |
145 | |
146 | === modified file 'test/test_application_notifications.js' |
147 | --- test/test_application_notifications.js 2013-01-17 16:19:17 +0000 |
148 | +++ test/test_application_notifications.js 2013-01-24 19:23:21 +0000 |
149 | @@ -2,7 +2,7 @@ |
150 | |
151 | describe('juju application notifications', function() { |
152 | var _setTimeout, _viewsHighlightRow, db, ERR_EV, juju, models, NO_OP, |
153 | - viewContainer, views, Y; |
154 | + viewContainer, views, Y, willError; |
155 | |
156 | before(function(done) { |
157 | Y = YUI(GlobalConfig).use(['node', |
158 | @@ -22,6 +22,18 @@ |
159 | ERR_EV = { |
160 | err: true |
161 | }; |
162 | + |
163 | + /** |
164 | + * A function that accepts a callback as its last (rightmost) argument and |
165 | + * calls that callback with a synthetic error event. |
166 | + */ |
167 | + willError = function() { |
168 | + // The last argument is the callback. We do not care what the |
169 | + // other arguments are or if they change in the future. |
170 | + var callback = arguments[arguments.length - 1]; |
171 | + callback(ERR_EV); |
172 | + }; |
173 | + |
174 | NO_OP = function() {}; |
175 | }); |
176 | |
177 | @@ -91,12 +103,8 @@ |
178 | }, |
179 | db: db, |
180 | env: { |
181 | - add_unit: function(serviceId, delta, callback) { |
182 | - callback(ERR_EV); |
183 | - }, |
184 | - remove_units: function(param, callback) { |
185 | - callback(ERR_EV); |
186 | - } |
187 | + add_unit: willError, |
188 | + remove_units: willError |
189 | }, |
190 | model: { |
191 | getAttrs: NO_OP, |
192 | @@ -140,9 +148,8 @@ |
193 | { err: true, |
194 | unit_names: ['aaa']}); |
195 | }, |
196 | - resolved: function(unit_name, relation_name, retry, callback) { |
197 | - callback(ERR_EV); |
198 | - }}, |
199 | + resolved: willError |
200 | + }, |
201 | unit: {}, |
202 | querystring: {} |
203 | }); |
204 | @@ -257,10 +264,7 @@ |
205 | }}, |
206 | getModelURL: NO_OP, |
207 | db: db, |
208 | - env: |
209 | - { set_constraints: function(id, values, callback) { |
210 | - callback(ERR_EV); |
211 | - }}, |
212 | + env: {set_constraints: willError}, |
213 | container: viewContainer}).render(); |
214 | |
215 | view.updateConstraints(); |
216 | @@ -274,15 +278,9 @@ |
217 | var view = new views.service_config( |
218 | { db: db, |
219 | env: { |
220 | - set_config: function(id, newValues, callback) { |
221 | - callback(ERR_EV); |
222 | - }, |
223 | - expose: function(id, callback) { |
224 | - callback(ERR_EV); |
225 | - }, |
226 | - unexpose: function(id, callback) { |
227 | - callback({err: true, service_name: '1234'}); |
228 | - } |
229 | + set_config: willError, |
230 | + expose: willError, |
231 | + unexpose: willError |
232 | }, |
233 | getModelURL: NO_OP, |
234 | model: { |
235 | @@ -329,11 +327,7 @@ |
236 | |
237 | var view = new views.service_relations( |
238 | { db: db, |
239 | - env: { |
240 | - remove_relation: function(id, newValues, callback) { |
241 | - callback(ERR_EV); |
242 | - } |
243 | - }, |
244 | + env: {remove_relation: willError}, |
245 | getModelURL: NO_OP, |
246 | container: viewContainer}); |
247 | |
248 | @@ -388,11 +382,7 @@ |
249 | return {get: NO_OP}; |
250 | } |
251 | }, |
252 | - env = { |
253 | - deploy: function(charmUrl, serviceName, config, callback) { |
254 | - callback(ERR_EV); |
255 | - } |
256 | - }, |
257 | + env = {deploy: willError}, |
258 | mockView = { |
259 | fire: NO_OP, |
260 | _deployCallback: function() { |
261 | @@ -418,7 +408,7 @@ |
262 | } |
263 | }; |
264 | |
265 | - views.charm.prototype.on_charm_deploy.apply(mockView, [ERR_EV]); |
266 | + views.charm.prototype.on_charm_deploy.call(mockView, ERR_EV); |
267 | assert.isTrue(notified); |
268 | }); |
269 | |
270 | |
271 | === modified file 'test/test_env.js' |
272 | --- test/test_env.js 2013-01-24 04:11:52 +0000 |
273 | +++ test/test_env.js 2013-01-24 19:23:21 +0000 |
274 | @@ -10,7 +10,7 @@ |
275 | var Y; |
276 | |
277 | describe('Juju environment', function() { |
278 | - var juju, conn, env, msg, testUtils; |
279 | + var juju, conn, env, msg, testUtils, endpoint1, endpoint2; |
280 | |
281 | before(function(done) { |
282 | Y = YUI(GlobalConfig).use( |
283 | @@ -26,9 +26,13 @@ |
284 | }); |
285 | }); |
286 | |
287 | - after(function(done) { |
288 | + beforeEach(function() { |
289 | + endpoint1 = ['service1', {name: 'relation-name-1'}]; |
290 | + endpoint2 = ['service2', {name: 'relation-name-2'}]; |
291 | + }); |
292 | + |
293 | + after(function() { |
294 | env.destroy(); |
295 | - done(); |
296 | }); |
297 | |
298 | it('can deploy a service', function() { |
299 | @@ -217,7 +221,7 @@ |
300 | }; |
301 | |
302 | it('denies adding a relation if the GUI is read-only', function() { |
303 | - assertOperationDenied('add_relation', ['haproxy:http', 'django:http']); |
304 | + assertOperationDenied('add_relation', [endpoint1, endpoint2]); |
305 | }); |
306 | |
307 | it('denies adding a unit if the GUI is read-only', function() { |
308 | @@ -242,8 +246,7 @@ |
309 | }); |
310 | |
311 | it('denies removing a relation if the GUI is read-only', function() { |
312 | - assertOperationDenied( |
313 | - 'remove_relation', ['haproxy:http', 'django:http']); |
314 | + assertOperationDenied('remove_relation', [endpoint1, endpoint2]); |
315 | }); |
316 | |
317 | it('denies removing units if the GUI is read-only', function() { |
318 | |
319 | === modified file 'test/test_topology_relation.js' |
320 | --- test/test_topology_relation.js 2013-01-23 16:46:40 +0000 |
321 | +++ test/test_topology_relation.js 2013-01-24 19:23:21 +0000 |
322 | @@ -39,12 +39,12 @@ |
323 | |
324 | it('fires a "clearState" event if a drag line is clicked', function() { |
325 | var firedEventName; |
326 | - var fauxTopo = { |
327 | + var topo = { |
328 | fire: function(eventName) { |
329 | firedEventName = eventName; |
330 | } |
331 | }; |
332 | - view.set('component', fauxTopo); |
333 | + view.set('component', topo); |
334 | view.draglineClicked(undefined, view); |
335 | assert.equal(firedEventName, 'clearState'); |
336 | }); |
337 | @@ -57,4 +57,37 @@ |
338 | assert.equal(view.render(), view); |
339 | }); |
340 | |
341 | + it('retrieves the current relation DOM element when removing', function() { |
342 | + var requestedSelector; |
343 | + var container = { |
344 | + one: function(selector) { |
345 | + requestedSelector = selector; |
346 | + } |
347 | + }; |
348 | + var env = { |
349 | + remove_relation: function() {} |
350 | + }; |
351 | + var topo = { |
352 | + get: function() { |
353 | + return env; |
354 | + } |
355 | + }; |
356 | + var fauxView = { |
357 | + get: function(name) { |
358 | + if (name === 'component') { |
359 | + return topo; |
360 | + } else if (name === 'container') { |
361 | + return container; |
362 | + } |
363 | + } |
364 | + }; |
365 | + var relationId = 'the ID of this relation'; |
366 | + var relation = { |
367 | + relation_id: relationId, |
368 | + endpoints: [null, null] |
369 | + }; |
370 | + view.removeRelation.call(fauxView, relation, fauxView, undefined); |
371 | + assert.equal(requestedSelector, '#' + relationId); |
372 | + }); |
373 | + |
374 | }); |
Land as is after landing parent branch, looks good to me with the change
involved in the parent.
https:/ /codereview. appspot. com/7206047/