Merge lp:~benji/juju-gui/bug-1103477 into lp:juju-gui/experimental

Proposed by Benji York
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
Reviewer Review Type Date Requested Status
Juju GUI Hackers Pending
Review via email: mp+144594@code.launchpad.net

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.

https://codereview.appspot.com/7206047/

To post a comment you must log in.
Revision history for this message
Madison Scott-Clary (makyo) wrote :

Land as is after landing parent branch, looks good to me with the change
involved in the parent.

https://codereview.appspot.com/7206047/

Revision history for this message
Gary Poster (gary) wrote :

Land with changes.

Extremely nice branch, Benji. Thank you.

Gary

https://codereview.appspot.com/7206047/diff/1/app/views/topology/relation.js
File app/views/topology/relation.js (right):

https://codereview.appspot.com/7206047/diff/1/app/views/topology/relation.js#newcode834
app/views/topology/relation.js:834: relationClick: function(d, self) {
I expected you to change this "d" argument to "relation" like your other
nice changes. Would be nice. :-)

https://codereview.appspot.com/7206047/diff/1/app/views/utils.js
File app/views/utils.js (right):

https://codereview.appspot.com/7206047/diff/1/app/views/utils.js#newcode827
app/views/utils.js:827: * Decorate a relation with some related/derrived
data.
typo: derived

https://codereview.appspot.com/7206047/

lp:~benji/juju-gui/bug-1103477 updated
346. By Benji York

merge from trunk

347. By Benji York

give a parameter a better name

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
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 });

Subscribers

People subscribed via source and target branches