Rietveld Code Review Tool
Help | Bug tracker | Discussion group | Source code | Sign in
(1395)

Delta Between Two Patch Sets: test/test_service_view.js

Issue 6733060: Filter buttons should match design
Left Patch Set: Created 12 years, 5 months ago
Right Patch Set: Filter buttons should match design Created 12 years, 5 months ago
Left:
Right:
Use n/p to move between diff chunks; N/P to move between comments. Please Sign in to add in-line comments.
Jump to:
Left: Side by side diff | Download
Right: Side by side diff | Download
« no previous file with change/comment | « lib/views/stylesheet.less ('k') | no next file » | no next file with change/comment »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
LEFTRIGHT
1 'use strict'; 1 'use strict';
2 2
3 (function() { 3 (function() {
4 describe('juju service view', function() { 4 describe('juju service view', function() {
5 var ServiceView, ServiceRelationsView, models, Y, container, service, db, 5 var models, Y, container, service, db, conn, env, charm, ENTER, ESC,
6 conn, env, app, charm, ENTER, ESC; 6 makeServiceView, makeServiceRelationsView, views, unit;
7 7
8 before(function(done) { 8 before(function(done) {
9 Y = YUI(GlobalConfig).use( 9 Y = YUI(GlobalConfig).use(
10 'juju-views', 'juju-models', 'base', 'node', 'json-parse', 10 'juju-views', 'juju-models', 'base', 'node', 'json-parse',
11 'juju-env', 'node-event-simulate', 'juju-tests-utils', 'event-key', 11 'juju-env', 'node-event-simulate', 'juju-tests-utils', 'event-key',
12 function(Y) { 12 function(Y) {
13 ENTER = Y.Node.DOM_EVENTS.key.eventDef.KEY_MAP.enter; 13 ENTER = Y.Node.DOM_EVENTS.key.eventDef.KEY_MAP.enter;
14 ESC = Y.Node.DOM_EVENTS.key.eventDef.KEY_MAP.esc; 14 ESC = Y.Node.DOM_EVENTS.key.eventDef.KEY_MAP.esc;
15 models = Y.namespace('juju.models'); 15 models = Y.namespace('juju.models');
16 ServiceView = Y.namespace('juju.views').service; 16 views = Y.namespace('juju.views');
17 ServiceRelationsView = Y.namespace('juju.views').service_relations;
18 done(); 17 done();
19 }); 18 });
20 }); 19 });
21 20
22 beforeEach(function(done) { 21 beforeEach(function(done) {
23 conn = new (Y.namespace('juju-tests.utils')).SocketStub(), 22 conn = new (Y.namespace('juju-tests.utils')).SocketStub(),
24 env = new (Y.namespace('juju')).Environment({conn: conn}); 23 env = new (Y.namespace('juju')).Environment({conn: conn});
25 env.connect(); 24 env.connect();
26 conn.open(); 25 conn.open();
27 container = Y.Node.create('<div id="test-container" />'); 26 container = Y.Node.create('<div id="test-container" />');
28 Y.one('#main').append(container); 27 Y.one('#main').append(container);
29 db = new models.Database(); 28 db = new models.Database();
30 app = { env: env, db: db, 29 charm = new models.Charm({id: 'cs:precise/mysql-7', description: 'A DB'});
31 getModelURL: function(model, intent) {
32 return model.get('name'); }};
33 charm = new models.Charm({id: 'cs:precise/mysql',
34 description: 'A DB'});
35 db.charms.add([charm]); 30 db.charms.add([charm]);
36 // Add units sorted by id as that is what we expect from the server. 31 // Add units sorted by id as that is what we expect from the server.
37 db.units.add([{id: 'mysql/0', agent_state: 'pending'}, 32 db.units.add([{id: 'mysql/0', agent_state: 'pending'},
38 {id: 'mysql/1', agent_state: 'pending'}, 33 {id: 'mysql/1', agent_state: 'pending'},
39 {id: 'mysql/2', agent_state: 'pending'} 34 {id: 'mysql/2', agent_state: 'pending'}
40 ]); 35 ]);
41 service = new models.Service({ 36 service = new models.Service(
42 id: 'mysql', 37 { id: 'mysql',
43 charm: 'cs:precise/mysql', 38 charm: 'cs:precise/mysql-7',
44 unit_count: db.units.size(), 39 unit_count: db.units.size(),
45 exposed: false}); 40 loaded: true,
41 exposed: false});
46 42
47 db.services.add([service]); 43 db.services.add([service]);
44 var viewMakerMaker = function(ViewPrototype) {
45 return function(querystring) {
46 if (!Y.Lang.isValue(querystring)) {
47 querystring = {};
48 }
49 return new ViewPrototype(
50 { container: container,
51 model: service,
52 db: db,
53 env: env,
54 getModelURL: function(model, intent) {
55 return model.get('name');
56 },
57 querystring: querystring}).render();
58 };
59 };
60 makeServiceView = viewMakerMaker(views.service);
61 makeServiceRelationsView = viewMakerMaker(views.service_relations);
48 done(); 62 done();
49 }); 63 });
50 64
51 afterEach(function(done) { 65 afterEach(function(done) {
52 container.remove(true); 66 container.remove(true);
53 service.destroy(); 67 service.destroy();
54 db.destroy(); 68 db.destroy();
55 env.destroy(); 69 env.destroy();
56 done(); 70 done();
57 }); 71 });
58 72
59 it('should show controls to modify units by default', function() { 73 it('should show controls to modify units by default', function() {
60 var view = new ServiceView( 74 var view = makeServiceView();
61 { container: container, model: service,
62 app: app, querystring: {}}).render();
63 container.one('#num-service-units').should.not.equal(null); 75 container.one('#num-service-units').should.not.equal(null);
64 }); 76 });
65 77
66 it('should not show controls if the charm is subordinate', function() { 78 it('should not show controls if the charm is subordinate', function() {
67 charm.set('is_subordinate', true); 79 charm.set('is_subordinate', true);
68 var view = new ServiceView( 80 var view = makeServiceView();
69 { container: container, service: service, app: app,
70 querystring: {}}).render();
71 // "var _ =" makes the linter happy. 81 // "var _ =" makes the linter happy.
72 var _ = expect(container.one('#num-service-units')).to.not.exist; 82 var _ = expect(container.one('#num-service-units')).to.not.exist;
73 }); 83 });
74 84
75 it('should show the service units ordered by number', function() { 85 it('should show the service units ordered by number', function() {
76 // Note that the units are added in beforeEach in an ordered manner. 86 // Note that the units are added in beforeEach in an ordered manner.
77 var view = new ServiceView( 87 var view = makeServiceView();
78 { container: container, model: service, app: app,
79 querystring: {}}).render();
80 var rendered_names = container.one( 88 var rendered_names = container.one(
81 'ul.thumbnails').all('div.unit').get('id'); 89 'ul.thumbnails').all('div.unit').get('id');
82 var expected_names = db.units.map(function(u) {return u.id;}); 90 var expected_names = db.units.map(function(u) {return u.id;});
83 expected_names.sort(); 91 expected_names.sort();
84 assert.deepEqual(rendered_names, expected_names); 92 assert.deepEqual(rendered_names, expected_names);
85 rendered_names.should.eql(expected_names); 93 rendered_names.should.eql(expected_names);
86 }); 94 });
87 95
88 it('should show unit details when a unit is clicked', function() { 96 it('should show unit details when a unit is clicked', function() {
89 // Note that the units are added in beforeEach in an ordered manner. 97 // Note that the units are added in beforeEach in an ordered manner.
90 var view = new ServiceView( 98 var view = makeServiceView(),
91 {container: container, model: service, app: app, 99 unit = container.one('ul.thumbnails').one('div.unit'),
92 querystring: {}}).render();
93 var unit = container.one('ul.thumbnails').one('div.unit'),
94 showUnitCalled = false; 100 showUnitCalled = false;
95 view.on('*:showUnit', function() { 101 view.on('*:showUnit', function() {
96 showUnitCalled = true; 102 showUnitCalled = true;
97 }); 103 });
98 unit.simulate('click'); 104 unit.simulate('click');
99 assert.isTrue(showUnitCalled); 105 assert.isTrue(showUnitCalled);
100 }); 106 });
101 107
102 it('should use the show_units_large template if required', function() { 108 it('should use the show_units_large template if required', function() {
103 // Note that the units are added in beforeEach in an ordered manner. 109 // Note that the units are added in beforeEach in an ordered manner.
104 var view = new ServiceView( 110 var view = makeServiceView();
105 {container: container, model: service, app: app,
106 querystring: {}}).render();
107 assert.equal('unit-large', container.one('ul.thumbnails').get('id')); 111 assert.equal('unit-large', container.one('ul.thumbnails').get('id'));
108 }); 112 });
109 113
110 var addUnits = function(number, state) { 114 var addUnits = function(number, state) {
111 var units = []; 115 var units = [];
112 // Starting from the number of already present units. 116 // Starting from the number of already present units.
113 var starting_from = db.units.size(); 117 var starting_from = db.units.size();
114 for (var i = starting_from; i < number + starting_from; i += 1) { 118 for (var i = starting_from; i < number + starting_from; i += 1) {
115 units.push({id: 'mysql/' + i, agent_state: state || 'pending'}); 119 units.push({id: 'mysql/' + i, agent_state: state || 'pending'});
116 } 120 }
117 db.units.add(units); 121 db.units.add(units);
118 }; 122 };
119 123
120 it('should use the show_units_medium template if required', function() { 124 it('should use the show_units_medium template if required', function() {
121 // Note that the units are added in beforeEach in an ordered manner. 125 // Note that the units are added in beforeEach in an ordered manner.
122 addUnits(30); 126 addUnits(30);
123 var view = new ServiceView( 127 var view = makeServiceView();
124 {container: container, model: service, app: app,
125 querystring: {}}).render();
126 assert.equal('unit-medium', container.one('ul.thumbnails').get('id')); 128 assert.equal('unit-medium', container.one('ul.thumbnails').get('id'));
127 }); 129 });
128 130
129 it('should use the show_units_small template if required', function() { 131 it('should use the show_units_small template if required', function() {
130 // Note that the units are added in beforeEach in an ordered manner. 132 // Note that the units are added in beforeEach in an ordered manner.
131 addUnits(60); 133 addUnits(60);
132 var view = new ServiceView( 134 var view = makeServiceView();
133 {container: container, model: service, app: app,
134 querystring: {}}).render();
135 assert.equal('unit-small', container.one('ul.thumbnails').get('id')); 135 assert.equal('unit-small', container.one('ul.thumbnails').get('id'));
136 }); 136 });
137 137
138 it('should use the show_units_tiny template if required', function() { 138 it('should use the show_units_tiny template if required', function() {
139 // Note that the units are added in beforeEach in an ordered manner. 139 // Note that the units are added in beforeEach in an ordered manner.
140 addUnits(260); 140 addUnits(260);
141 var view = new ServiceView( 141 var view = makeServiceView();
142 {container: container, model: service, app: app,
143 querystring: {}}).render();
144 assert.equal('unit-tiny', container.one('ul.thumbnails').get('id')); 142 assert.equal('unit-tiny', container.one('ul.thumbnails').get('id'));
145 }); 143 });
146 144
147 it('should display units based on their agent state', function() { 145 it('should display units based on their agent state', function() {
148 // Note that the units are added in beforeEach in an ordered manner 146 // Note that the units are added in beforeEach in an ordered manner
149 // with ``pending`` status. 147 // with ``pending`` status.
150 addUnits(1, 'started'); 148 addUnits(1, 'started');
151 addUnits(2, 'start-error'); 149 addUnits(2, 'start-error');
152 var view = new ServiceView( 150 var view = makeServiceView();
153 {container: container, model: service, app: app,
154 querystring: {}}).render();
155 var thumbnails = container.one('ul.thumbnails'); 151 var thumbnails = container.one('ul.thumbnails');
156 assert.equal(1, thumbnails.all('.state-started').size()); 152 assert.equal(1, thumbnails.all('.state-started').size());
157 assert.equal(2, thumbnails.all('.state-error').size()); 153 assert.equal(2, thumbnails.all('.state-error').size());
158 assert.equal(3, thumbnails.all('.state-pending').size()); 154 assert.equal(3, thumbnails.all('.state-pending').size());
159 }); 155 });
160 156
161 it('should start with the proper number of units shown in the text field', 157 it('should start with the proper number of units shown in the text field',
162 function() { 158 function() {
163 var view = new ServiceView( 159 var view = makeServiceView();
164 { container: container, model: service, app: app,
165 querystring: {}}).render();
166 var control = container.one('#num-service-units'); 160 var control = container.one('#num-service-units');
167 control.get('value').should.equal('3'); 161 control.get('value').should.equal('3');
168 }); 162 });
169 163
170 it('should remove multiple units when the text input changes', 164 it('should remove multiple units when the text input changes',
171 function() { 165 function() {
172 var view = new ServiceView( 166 var view = makeServiceView();
173 { container: container, model: service, app: app,
174 querystring: {}}).render();
175 var control = container.one('#num-service-units'); 167 var control = container.one('#num-service-units');
176 control.set('value', 1); 168 control.set('value', 1);
177 control.simulate('keydown', { keyCode: ENTER }); // Simulate Enter. 169 control.simulate('keydown', { keyCode: ENTER }); // Simulate Enter.
178 var message = conn.last_message(); 170 var message = conn.last_message();
179 message.op.should.equal('remove_units'); 171 message.op.should.equal('remove_units');
180 message.unit_names.should.eql(['mysql/2', 'mysql/1']); 172 message.unit_names.should.eql(['mysql/2', 'mysql/1']);
181 }); 173 });
182 174
183 it('should not do anything if requested is < 1', 175 it('should not do anything if requested is < 1',
184 function() { 176 function() {
185 var view = new ServiceView( 177 var view = makeServiceView();
186 { container: container, model: service, app: app,
187 querystring: {}}).render();
188 var control = container.one('#num-service-units'); 178 var control = container.one('#num-service-units');
189 control.set('value', 0); 179 control.set('value', 0);
190 control.simulate('keydown', { keyCode: ENTER }); 180 control.simulate('keydown', { keyCode: ENTER });
191 var _ = expect(conn.last_message()).to.not.exist; 181 var _ = expect(conn.last_message()).to.not.exist;
192 control.get('value').should.equal('3'); 182 control.get('value').should.equal('3');
193 }); 183 });
194 184
195 it('should not do anything if the number of units is <= 1', 185 it('should not do anything if the number of units is <= 1',
196 function() { 186 function() {
197 service.set('unit_count', 1); 187 service.set('unit_count', 1);
198 db.units.remove([1, 2]); 188 db.units.remove([1, 2]);
199 var view = new ServiceView( 189 var view = makeServiceView();
200 { container: container, model: service, app: app,
201 querystring: {}}).render();
202 var control = container.one('#num-service-units'); 190 var control = container.one('#num-service-units');
203 control.set('value', 0); 191 control.set('value', 0);
204 control.simulate('keydown', { keyCode: ENTER }); 192 control.simulate('keydown', { keyCode: ENTER });
205 var _ = expect(conn.last_message()).to.not.exist; 193 var _ = expect(conn.last_message()).to.not.exist;
206 control.get('value').should.equal('1'); 194 control.get('value').should.equal('1');
207 }); 195 });
208 196
209 it('should add the correct number of units when entered via text field', 197 it('should add the correct number of units when entered via text field',
210 function() { 198 function() {
211 var view = new ServiceView( 199 var view = makeServiceView();
212 { container: container, model: service, app: app,
213 querystring: {}}).render();
214 var control = container.one('#num-service-units'); 200 var control = container.one('#num-service-units');
215 control.set('value', 7); 201 control.set('value', 7);
216 control.simulate('keydown', { keyCode: ENTER }); 202 control.simulate('keydown', { keyCode: ENTER });
217 var message = conn.last_message(); 203 var message = conn.last_message();
218 message.op.should.equal('add_unit'); 204 message.op.should.equal('add_unit');
219 message.service_name.should.equal('mysql'); 205 message.service_name.should.equal('mysql');
220 message.num_units.should.equal(4); 206 message.num_units.should.equal(4);
221 }); 207 });
222 208
223 it('should add pending units as soon as it gets a reply back ' + 209 it('should add pending units as soon as it gets a reply back ' +
224 'from the server', 210 'from the server',
225 function() { 211 function() {
226 var new_unit_id = 'mysql/5'; 212 var new_unit_id = 'mysql/5',
227 var expected_names = db.units.map(function(u) {return u.id;}); 213 view = makeServiceView(),
214 control = container.one('#num-service-units'),
215 expected_names = db.units.map(function(u) {return u.id;});
228 expected_names.push(new_unit_id); 216 expected_names.push(new_unit_id);
229 expected_names.sort(); 217 expected_names.sort();
230 var view = new ServiceView(
231 { container: container, model: service, app: app,
232 querystring: {}}).render();
233 var control = container.one('#num-service-units');
234 control.set('value', 4); 218 control.set('value', 4);
235 control.simulate('keydown', { keyCode: ENTER }); 219 control.simulate('keydown', { keyCode: ENTER });
236 var callbacks = Y.Object.values(env._txn_callbacks); 220 var callbacks = Y.Object.values(env._txn_callbacks);
237 callbacks.length.should.equal(1); 221 callbacks.length.should.equal(1);
238 // Since we don't have an app to listen to this event and tell the 222 // Since we don't have an app to listen to this event and tell the
239 // view to re-render, we need to do it ourselves. 223 // view to re-render, we need to do it ourselves.
240 db.on('update', view.render, view); 224 db.on('update', view.render, view);
241 callbacks[0]({result: [new_unit_id]}); 225 callbacks[0]({result: [new_unit_id]});
242 var db_names = db.units.map(function(u) {return u.id;}); 226 var db_names = db.units.map(function(u) {return u.id;});
243 db_names.sort(); 227 db_names.sort();
244 db_names.should.eql(expected_names); 228 db_names.should.eql(expected_names);
245 service.get('unit_count').should.equal(4); 229 service.get('unit_count').should.equal(4);
246 var rendered_names = container.one( 230 var rendered_names = container.one(
247 'ul.thumbnails').all('div.unit').get('id'); 231 'ul.thumbnails').all('div.unit').get('id');
248 assert.deepEqual(rendered_names, expected_names); 232 assert.deepEqual(rendered_names, expected_names);
249 }); 233 });
250 234
251 it('should remove units as soon as it gets a ' + 235 it('should remove units as soon as it gets a ' +
252 'reply back from the server', 236 'reply back from the server',
253 function() { 237 function() {
254 var view = new ServiceView( 238 var view = makeServiceView();
255 { container: container, model: service, app: app,
256 querystring: {}}).render();
257 var control = container.one('#num-service-units'); 239 var control = container.one('#num-service-units');
258 control.set('value', 2); 240 control.set('value', 2);
259 control.simulate('keydown', { keyCode: ENTER }); 241 control.simulate('keydown', { keyCode: ENTER });
260 var callbacks = Y.Object.values(env._txn_callbacks); 242 var callbacks = Y.Object.values(env._txn_callbacks);
261 callbacks.length.should.equal(1); 243 callbacks.length.should.equal(1);
262 callbacks[0]({unit_names: ['mysql/2']}); 244 callbacks[0]({unit_names: ['mysql/2']});
263 var _ = expect(db.units.getById('mysql/2')).to.not.exist; 245 var _ = expect(db.units.getById('mysql/2')).to.not.exist;
264 }); 246 });
265 247
266 it('should reset values on the control when you press escape', 248 it('should reset values on the control when you press escape',
267 function() { 249 function() {
268 var view = new ServiceView( 250 var view = makeServiceView();
269 { container: container, model: service, app: app,
270 querystring: {}}).render();
271 var control = container.one('#num-service-units'); 251 var control = container.one('#num-service-units');
272 control.set('value', 2); 252 control.set('value', 2);
273 control.simulate('keydown', { keyCode: ESC }); 253 control.simulate('keydown', { keyCode: ESC });
274 control.get('value').should.equal('3'); 254 control.get('value').should.equal('3');
275 }); 255 });
276 256
277 it('should reset values on the control when you change focus', 257 it('should reset values on the control when you change focus',
278 function() { 258 function() {
279 var view = new ServiceView( 259 var view = makeServiceView();
280 { container: container, model: service, app: app,
281 querystring: {}}).render();
282 var control = container.one('#num-service-units'); 260 var control = container.one('#num-service-units');
283 control.set('value', 2); 261 control.set('value', 2);
284 control.simulate('blur'); 262 control.simulate('blur');
285 control.get('value').should.equal('3'); 263 control.get('value').should.equal('3');
286 }); 264 });
287 265
288 it('should reset values on the control when you type invalid value', 266 it('should reset values on the control when you type invalid value',
289 function() { 267 function() {
290 var view = new ServiceView( 268 var view = makeServiceView();
291 { container: container, model: service, app: app,
292 querystring: {}}).render();
293 var control = container.one('#num-service-units'); 269 var control = container.one('#num-service-units');
294 270
295 var pressKey = function(key) { 271 var pressKey = function(key) {
296 control.set('value', key); 272 control.set('value', key);
297 control.simulate('keydown', { keyCode: ENTER }); 273 control.simulate('keydown', { keyCode: ENTER });
298 control.get('value').should.equal('3'); 274 control.get('value').should.equal('3');
299 }; 275 };
300 pressKey('a'); 276 pressKey('a');
301 pressKey('2w'); 277 pressKey('2w');
302 pressKey('w2'); 278 pressKey('w2');
303 }); 279 });
304 280
305 // Test for destroying services. 281 // Test for destroying services.
306 it('should destroy the service when "Destroy Service" is clicked', 282 it('should destroy the service when "Destroy Service" is clicked',
307 function() { 283 function() {
308 var view = new ServiceView( 284 var view = makeServiceView();
309 { container: container, model: service, app: app,
310 querystring: {}}).render();
311 var control = container.one('#destroy-service'); 285 var control = container.one('#destroy-service');
312 control.simulate('click'); 286 control.simulate('click');
313 var destroy = container.one('#destroy-modal-panel .btn-danger'); 287 var destroy = container.one('#destroy-modal-panel .btn-danger');
314 destroy.simulate('click'); 288 destroy.simulate('click');
315 var message = conn.last_message(); 289 var message = conn.last_message();
316 message.op.should.equal('destroy_service'); 290 message.op.should.equal('destroy_service');
317 destroy.get('disabled').should.equal(true); 291 destroy.get('disabled').should.equal(true);
318 }); 292 });
319 293
320 it('should remove the service from the db after server ack', 294 it('should remove the service from the db after server ack',
321 function() { 295 function() {
322 var view = new ServiceView( 296 var view = makeServiceView();
323 { container: container, model: service, app: app,
324 querystring: {}}).render();
325 db.relations.add( 297 db.relations.add(
326 [new models.Relation({id: 'relation-0000000000', 298 [new models.Relation({id: 'relation-0000000000',
327 endpoints: [['mysql', {}], ['wordpress', {}]]}), 299 endpoints: [['mysql', {}], ['wordpress', {}]]}),
328 new models.Relation({id: 'relation-0000000001', 300 new models.Relation({id: 'relation-0000000001',
329 endpoints: [['squid', {}], ['apache', {}]]})]); 301 endpoints: [['squid', {}], ['apache', {}]]})]);
330 var control = container.one('#destroy-service'); 302 var control = container.one('#destroy-service');
331 control.simulate('click'); 303 control.simulate('click');
332 var destroy = container.one('#destroy-modal-panel .btn-danger'); 304 var destroy = container.one('#destroy-modal-panel .btn-danger');
333 destroy.simulate('click'); 305 destroy.simulate('click');
334 var called = false; 306 var called = false;
335 view.on('showEnvironment', function(ev) { 307 view.on('showEnvironment', function(ev) {
336 called = true; 308 called = true;
337 }); 309 });
338 var callbacks = Y.Object.values(env._txn_callbacks); 310 var callbacks = Y.Object.values(env._txn_callbacks);
339 callbacks.length.should.equal(1); 311 callbacks.length.should.equal(1);
340 // Since we don't have an app to listen to this event and tell the 312 // Since we don't have an app to listen to this event and tell the
341 // view to re-render, we need to do it ourselves. 313 // view to re-render, we need to do it ourselves.
342 db.on('update', view.render, view); 314 db.on('update', view.render, view);
343 callbacks[0]({result: true}); 315 callbacks[0]({result: true});
344 var _ = expect(db.services.getById(service.get('id'))).to.not.exist; 316 var _ = expect(db.services.getById(service.get('id'))).to.not.exist;
345 db.relations.map(function(u) {return u.get('id');}) 317 db.relations.map(function(u) {return u.get('id');})
346 .should.eql(['relation-0000000001']); 318 .should.eql(['relation-0000000001']);
347 // Catch show environment event. 319 // Catch show environment event.
348 called.should.equal(true); 320 called.should.equal(true);
349 }); 321 });
350 322
351 it('should send an expose RPC call when exposeService is invoked', 323 it('should send an expose RPC call when exposeService is invoked',
352 function() { 324 function() {
353 var view = new ServiceView({ 325 var view = makeServiceView();
354 container: container, model: service, app: app,
355 querystring: {}});
356 326
357 view.exposeService(); 327 view.exposeService();
358 conn.last_message().op.should.equal('expose'); 328 conn.last_message().op.should.equal('expose');
359 }); 329 });
360 330
361 it('should send an unexpose RPC call when unexposeService is invoked', 331 it('should send an unexpose RPC call when unexposeService is invoked',
362 function() { 332 function() {
363 var view = new ServiceView({ 333 var view = makeServiceView();
364 container: container, model: service, app: app,
365 querystring: {}});
366 334
367 view.unexposeService(); 335 view.unexposeService();
368 conn.last_message().op.should.equal('unexpose'); 336 conn.last_message().op.should.equal('unexpose');
369 }); 337 });
370 338
371 it('should invoke callback when expose RPC returns', 339 it('should invoke callback when expose RPC returns',
372 function() { 340 function() {
373 var view = new ServiceView({ 341 var view = makeServiceView();
374 container: container, model: service, app: app,
375 querystring: {}}).render();
376 342
377 var test = function(selectorBefore, selectorAfter, callback) { 343 var test = function(selectorBefore, selectorAfter, callback) {
378 console.log('Service is exposed: ' + service.get('exposed')); 344 console.log('Service is exposed: ' + service.get('exposed'));
379 console.log('selectorBefore: ' + selectorBefore); 345 console.log('selectorBefore: ' + selectorBefore);
380 console.log('selectorAfter: ' + selectorAfter); 346 console.log('selectorAfter: ' + selectorAfter);
381 347
382 assert.isNotNull(container.one(selectorBefore)); 348 assert.isNotNull(container.one(selectorBefore));
383 assert.isNull(container.one(selectorAfter)); 349 assert.isNull(container.one(selectorAfter));
384 350
385 var dbUpdated = false; 351 var dbUpdated = false;
(...skipping 11 matching lines...) Expand all
397 assert.isNull(container.one(selectorBefore)); 363 assert.isNull(container.one(selectorBefore));
398 }; 364 };
399 365
400 test('.exposeService', '.unexposeService', 366 test('.exposeService', '.unexposeService',
401 Y.bind(view._exposeServiceCallback, view)); 367 Y.bind(view._exposeServiceCallback, view));
402 test('.unexposeService', '.exposeService', 368 test('.unexposeService', '.exposeService',
403 Y.bind(view._unexposeServiceCallback, view)); 369 Y.bind(view._unexposeServiceCallback, view));
404 }); 370 });
405 371
406 it('should show proper tabs initially', function() { 372 it('should show proper tabs initially', function() {
407 var view = new ServiceView( 373 var view = makeServiceView(),
408 { container: container, model: service, app: app,
409 querystring: {}}).render(),
410 active_navtabs = []; 374 active_navtabs = [];
411 container.all('.state-title').each( 375 container.all('.state-title').each(
412 function(n) { 376 function(n) {
413 active_navtabs.push([n.get('text').trim(), 377 active_navtabs.push([n.get('text').trim(),
414 n.hasClass('active')]); 378 n.hasClass('active')]);
415 }); 379 });
416 active_navtabs.should.eql( 380 active_navtabs.should.eql(
417 [['All', true], 381 [['All', true],
418 ['Running', false], 382 ['Running', false],
419 ['Pending', false], 383 ['Pending', false],
420 ['Error', false]]); 384 ['Error', false]]);
421 }); 385 });
422 386
423 it('should show zero running units when filtered', function() { 387 it('should show zero running units when filtered', function() {
424 // All units are pending. 388 // All units are pending.
425 var view = new ServiceView( 389 var view = makeServiceView({state: 'running'}),
426 { container: container, model: service, app: app,
427 querystring: {state: 'running'}}).render(),
428 active_navtabs = []; 390 active_navtabs = [];
429 container.all('.state-title').each( 391 container.all('.state-title').each(
430 function(n) { 392 function(n) {
431 active_navtabs.push([n.get('text').trim(), 393 active_navtabs.push([n.get('text').trim(),
432 n.hasClass('active')]); 394 n.hasClass('active')]);
433 }); 395 });
434 active_navtabs.should.eql( 396 active_navtabs.should.eql(
435 [['All', false], 397 [['All', false],
436 ['Running', true], 398 ['Running', true],
437 ['Pending', false], 399 ['Pending', false],
438 ['Error', false]]); 400 ['Error', false]]);
439 container.all('div.thumbnail').get('id').length.should.equal(0); 401 container.all('div.thumbnail').get('id').length.should.equal(0);
440 }); 402 });
441 403
442 it('should show some running units when filtered', function() { 404 it('should show some running units when filtered', function() {
443 db.units.getById('mysql/0').agent_state = 'started'; 405 db.units.getById('mysql/0').agent_state = 'started';
444 // 1 is pending. 406 // 1 is pending.
445 db.units.getById('mysql/2').agent_state = 'started'; 407 db.units.getById('mysql/2').agent_state = 'started';
446 var view = new ServiceView( 408 var view = makeServiceView({state: 'running'});
447 { container: container, model: service, app: app,
448 querystring: {state: 'running'}}).render();
449 var rendered_names = container.one( 409 var rendered_names = container.one(
450 'ul.thumbnails').all('div.unit').get('id'); 410 'ul.thumbnails').all('div.unit').get('id');
451 rendered_names.should.eql(['mysql/0', 'mysql/2']); 411 rendered_names.should.eql(['mysql/0', 'mysql/2']);
452 }); 412 });
453 413
454 it('should show zero pending units when filtered', function() { 414 it('should show zero pending units when filtered', function() {
455 db.units.getById('mysql/0').agent_state = 'install-error'; 415 db.units.getById('mysql/0').agent_state = 'install-error';
456 db.units.getById('mysql/1').agent_state = 'error'; 416 db.units.getById('mysql/1').agent_state = 'error';
457 db.units.getById('mysql/2').agent_state = 'started'; 417 db.units.getById('mysql/2').agent_state = 'started';
458 var view = new ServiceView( 418 var view = makeServiceView({state: 'pending'}),
459 { container: container, model: service, app: app,
460 querystring: {state: 'pending'}}).render(),
461 active_navtabs = []; 419 active_navtabs = [];
462 container.all('.state-title').each( 420 container.all('.state-title').each(
463 function(n) { 421 function(n) {
464 active_navtabs.push([n.get('text').trim(), 422 active_navtabs.push([n.get('text').trim(),
465 n.hasClass('active')]); 423 n.hasClass('active')]);
466 }); 424 });
467 active_navtabs.should.eql( 425 active_navtabs.should.eql(
468 [['All', false], 426 [['All', false],
469 ['Running', false], 427 ['Running', false],
470 ['Pending', true], 428 ['Pending', true],
471 ['Error', false]]); 429 ['Error', false]]);
472 container.all('div.thumbnail').get('id').length.should.equal(0); 430 container.all('div.thumbnail').get('id').length.should.equal(0);
473 }); 431 });
474 432
475 it('should show some pending units when filtered', function() { 433 it('should show some pending units when filtered', function() {
476 // 0 is pending already. 434 // 0 is pending already.
477 db.units.getById('mysql/1').agent_state = 'started'; 435 db.units.getById('mysql/1').agent_state = 'started';
478 // We include installed with pending. 436 // We include installed with pending.
479 db.units.getById('mysql/2').agent_state = 'installed'; 437 db.units.getById('mysql/2').agent_state = 'installed';
480 var view = new ServiceView( 438 var view = makeServiceView({state: 'pending'});
481 { container: container, model: service, app: app,
482 querystring: {state: 'pending'}}).render();
483 var rendered_names = container.one( 439 var rendered_names = container.one(
484 'ul.thumbnails').all('div.unit').get('id'); 440 'ul.thumbnails').all('div.unit').get('id');
485 rendered_names.should.eql(['mysql/0', 'mysql/2']); 441 rendered_names.should.eql(['mysql/0', 'mysql/2']);
486 }); 442 });
487 443
488 it('should show zero error units when filtered', function() { 444 it('should show zero error units when filtered', function() {
489 var view = new ServiceView( 445 var view = makeServiceView({state: 'error'}),
490 { container: container, model: service, app: app,
491 querystring: {state: 'error'}}).render(),
492 active_navtabs = []; 446 active_navtabs = [];
493 container.all('.state-title').each( 447 container.all('.state-title').each(
494 function(n) { 448 function(n) {
495 active_navtabs.push([n.get('text').trim(), 449 active_navtabs.push([n.get('text').trim(),
496 n.hasClass('active')]); 450 n.hasClass('active')]);
497 }); 451 });
498 active_navtabs.should.eql( 452 active_navtabs.should.eql(
499 [['All', false], 453 [['All', false],
500 ['Running', false], 454 ['Running', false],
501 ['Pending', false], 455 ['Pending', false],
502 ['Error', true]]); 456 ['Error', true]]);
503 container.all('div.thumbnail').get('id').length.should.equal(0); 457 container.all('div.thumbnail').get('id').length.should.equal(0);
504 }); 458 });
505 459
506 it('should show some error units when filtered', function() { 460 it('should show some error units when filtered', function() {
507 // Any -error is included. 461 // Any -error is included.
508 db.units.getById('mysql/0').agent_state = 'install-error'; 462 db.units.getById('mysql/0').agent_state = 'install-error';
509 // 1 is pending. 463 // 1 is pending.
510 db.units.getById('mysql/2').agent_state = 'foo-error'; 464 db.units.getById('mysql/2').agent_state = 'foo-error';
511 var view = new ServiceView( 465 var view = makeServiceView({state: 'error'}),
512 { container: container, model: service, app: app, 466 rendered_names = container.one(
513 querystring: {state: 'error'}}).render();
514 var rendered_names = container.one(
515 'ul.thumbnails').all('div.unit').get('id'); 467 'ul.thumbnails').all('div.unit').get('id');
516 rendered_names.should.eql(['mysql/0', 'mysql/2']); 468 rendered_names.should.eql(['mysql/0', 'mysql/2']);
517 }); 469 });
518 470
519 it('should remove the relation when requested', 471 it('should remove the relation when requested',
520 function() { 472 function() {
521
522 var service_name = service.get('id'), 473 var service_name = service.get('id'),
523 rel0 = new models.Relation( 474 rel0 = new models.Relation(
524 { id: 'relation-0', 475 { id: 'relation-0',
525 endpoints: 476 endpoints:
526 [[service_name, {name: 'db', role: 'source'}], 477 [[service_name, {name: 'db', role: 'source'}],
527 ['squid', {name: 'cache', role: 'front'}]], 478 ['squid', {name: 'cache', role: 'front'}]],
528 'interface': 'cache', 479 'interface': 'cache',
529 scope: 'global' 480 scope: 'global'
530 }), 481 }),
531 rel1 = new models.Relation( 482 rel1 = new models.Relation(
532 { id: 'relation-1', 483 { id: 'relation-1',
533 endpoints: 484 endpoints:
534 [[service_name, {name: 'db', role: 'peer'}]], 485 [[service_name, {name: 'db', role: 'peer'}]],
535 'interface': 'db', 486 'interface': 'db',
536 scope: 'global' 487 scope: 'global'
537 }); 488 });
538 489
539 db.relations.add([rel0, rel1]); 490 db.relations.add([rel0, rel1]);
540 491
541 var view = new ServiceRelationsView( 492 var view = makeServiceRelationsView(),
542 { container: container, model: service, app: app, 493 control = container.one('#relation-0');
543 querystring: {}}).render();
544
545 var control = container.one('#relation-0');
546 control.simulate('click'); 494 control.simulate('click');
547 var remove = container.one('#remove-modal-panel .btn-danger'); 495 var remove = container.one('#remove-modal-panel .btn-danger');
548 remove.simulate('click'); 496 remove.simulate('click');
549 var message = conn.last_message(); 497 var message = conn.last_message();
550 message.op.should.equal('remove_relation'); 498 message.op.should.equal('remove_relation');
551 remove.get('disabled').should.equal(true); 499 remove.get('disabled').should.equal(true);
552 }); 500 });
553 501
554 it('should remove peer relations when requested', 502 it('should remove peer relations when requested',
555 function() { 503 function() {
(...skipping 10 matching lines...) Expand all
566 rel1 = new models.Relation( 514 rel1 = new models.Relation(
567 { id: 'relation-1', 515 { id: 'relation-1',
568 endpoints: 516 endpoints:
569 [[service_name, {name: 'db', role: 'peer'}]], 517 [[service_name, {name: 'db', role: 'peer'}]],
570 'interface': 'db', 518 'interface': 'db',
571 scope: 'global' 519 scope: 'global'
572 }); 520 });
573 521
574 db.relations.add([rel0, rel1]); 522 db.relations.add([rel0, rel1]);
575 523
576 var view = new ServiceRelationsView( 524 var view = makeServiceRelationsView(),
577 { container: container, model: service, app: app, 525 control = container.one('#relation-1');
578 querystring: {}}).render();
579
580 var control = container.one('#relation-1');
581 control.simulate('click'); 526 control.simulate('click');
582 var remove = container.one('#remove-modal-panel .btn-danger'); 527 var remove = container.one('#remove-modal-panel .btn-danger');
583 remove.simulate('click'); 528 remove.simulate('click');
584 var message = conn.last_message(); 529 var message = conn.last_message();
585 message.op.should.equal('remove_relation'); 530 message.op.should.equal('remove_relation');
586 remove.get('disabled').should.equal(true); 531 remove.get('disabled').should.equal(true);
587 }); 532 });
588 533
589 it('should remove two consecutive relations when requested', 534 it('should remove two consecutive relations when requested',
590 function() { 535 function() {
(...skipping 13 matching lines...) Expand all
604 endpoints: 549 endpoints:
605 [[service_name, {name: 'db', role: 'peer'}]], 550 [[service_name, {name: 'db', role: 'peer'}]],
606 'interface': 'db', 551 'interface': 'db',
607 scope: 'global' 552 scope: 'global'
608 }); 553 });
609 554
610 db.relations.add([rel0, rel1]); 555 db.relations.add([rel0, rel1]);
611 db.relations.get_relations_for_service( 556 db.relations.get_relations_for_service(
612 service).length.should.equal(2); 557 service).length.should.equal(2);
613 558
614 var view = new ServiceRelationsView( 559 var view = makeServiceRelationsView(),
615 { container: container, model: service, app: app, 560 control = container.one('#relation-0');
616 querystring: {}}).render();
617
618 var control = container.one('#relation-0');
619 control.simulate('click'); 561 control.simulate('click');
620 var remove = container.one('#remove-modal-panel .btn-danger'); 562 var remove = container.one('#remove-modal-panel .btn-danger');
621 remove.simulate('click'); 563 remove.simulate('click');
622 env.dispatch_result(conn.last_message()); 564 env.dispatch_result(conn.last_message());
623 db.relations.get_relations_for_service( 565 db.relations.get_relations_for_service(
624 service).length.should.equal(1); 566 service).length.should.equal(1);
625 567
626 control = container.one('#relation-1'); 568 control = container.one('#relation-1');
627 control.simulate('click'); 569 control.simulate('click');
628 remove = container.one('#remove-modal-panel .btn-danger'); 570 remove = container.one('#remove-modal-panel .btn-danger');
(...skipping 17 matching lines...) Expand all
646 rel1 = new models.Relation( 588 rel1 = new models.Relation(
647 { id: 'relation-1', 589 { id: 'relation-1',
648 endpoints: 590 endpoints:
649 [[service_name, {name: 'db', role: 'peer'}]], 591 [[service_name, {name: 'db', role: 'peer'}]],
650 'interface': 'db', 592 'interface': 'db',
651 scope: 'global' 593 scope: 'global'
652 }); 594 });
653 595
654 db.relations.add([rel0, rel1]); 596 db.relations.add([rel0, rel1]);
655 597
656 var view = new ServiceRelationsView( 598 var view = makeServiceRelationsView({rel_id: 'relation-0'}),
657 { container: container, model: service, app: app, 599 row = container.one('.highlighted');
658 querystring: {rel_id: 'relation-0'}}).render();
659
660 var row = container.one('.highlighted');
661 row.one('a').getHTML().should.equal('squid'); 600 row.one('a').getHTML().should.equal('squid');
662 row.one('.btn').get('disabled').should.equal(false); 601 row.one('.btn').get('disabled').should.equal(false);
663 }); 602 });
664 603
665 it('should handle errors properly in the callback', 604 it('should handle errors properly in the callback',
666 function() { 605 function() {
667 var service_name = service.get('id'), 606 var service_name = service.get('id'),
668 rel0 = new models.Relation( 607 rel0 = new models.Relation(
669 { id: 'relation-0', 608 { id: 'relation-0',
670 endpoints: 609 endpoints:
671 [[service_name, {name: 'db', role: 'source'}], 610 [[service_name, {name: 'db', role: 'source'}],
672 ['squid', {name: 'cache', role: 'front'}]], 611 ['squid', {name: 'cache', role: 'front'}]],
673 'interface': 'cache', 612 'interface': 'cache',
674 scope: 'global' 613 scope: 'global'
675 }), 614 }),
676 rel1 = new models.Relation( 615 rel1 = new models.Relation(
677 { id: 'relation-1', 616 { id: 'relation-1',
678 endpoints: 617 endpoints:
679 [[service_name, {name: 'db', role: 'peer'}]], 618 [[service_name, {name: 'db', role: 'peer'}]],
680 'interface': 'db', 619 'interface': 'db',
681 scope: 'global' 620 scope: 'global'
682 }); 621 });
683 db.relations.add([rel0, rel1]); 622 db.relations.add([rel0, rel1]);
684 var view = new ServiceRelationsView( 623 var view = makeServiceRelationsView(),
685 { container: container, model: service, app: app, 624 control = container.one('#relation-0');
686 querystring: {}});
687 view.render();
688 var control = container.one('#relation-0');
689 control.simulate('click'); 625 control.simulate('click');
690 var remove = container.one('#remove-modal-panel .btn-danger'); 626 var remove = container.one('#remove-modal-panel .btn-danger');
691 remove.simulate('click'); 627 remove.simulate('click');
692 628
693 var callbacks = Y.Object.values(env._txn_callbacks); 629 var callbacks = Y.Object.values(env._txn_callbacks);
694 callbacks.length.should.equal(1); 630 callbacks.length.should.equal(1);
695 var existing_notice_count = db.notifications.size(); 631 var existing_notice_count = db.notifications.size();
696 callbacks[0]( 632 callbacks[0](
697 { err: true, endpoint_a: service_name, 633 { err: true, endpoint_a: service_name,
698 endpoint_b: 'squid'}); 634 endpoint_b: 'squid'});
(...skipping 18 matching lines...) Expand all
717 } 653 }
718 }, { 654 }, {
719 agent_state: 'pending', 655 agent_state: 'pending',
720 relation_errors: { 656 relation_errors: {
721 a: '', 657 a: '',
722 b: '' 658 b: ''
723 } 659 }
724 }, { 660 }, {
725 testKey: 'error2', 661 testKey: 'error2',
726 agent_state: 'error' 662 agent_state: 'error'
727 }], filtered = ServiceView.prototype.filterUnits('error', units); 663 }], filtered = views.service.prototype.filterUnits('error', units);
728 664
729 assert.equal(2, filtered.length); 665 assert.equal(2, filtered.length);
730 assert.equal('error1', filtered[0].testKey); 666 assert.equal('error1', filtered[0].testKey);
731 assert.equal('error2', filtered[1].testKey); 667 assert.equal('error2', filtered[1].testKey);
732 }); 668 });
733 669
734 }); 670 });
735 }) (); 671 }) ();
LEFTRIGHT

Powered by Google App Engine
RSS Feeds Recent Issues | This issue
This is Rietveld f62528b