Merge lp:~benji/juju-gui/reorganize-charmworld-api-part-A into lp:juju-gui/experimental

Proposed by Benji York
Status: Merged
Merged at revision: 1045
Proposed branch: lp:~benji/juju-gui/reorganize-charmworld-api-part-A
Merge into: lp:juju-gui/experimental
Diff against target: 1138 lines (+242/-172)
28 files modified
app/app.js (+3/-3)
app/models/charm.js (+6/-5)
app/models/model-controller.js (+1/-1)
app/store/charm.js (+106/-64)
app/subapps/browser/browser.js (+2/-2)
app/subapps/browser/views/charm.js (+1/-1)
app/subapps/browser/views/charmresults.js (+2/-2)
app/subapps/browser/views/view.js (+1/-1)
app/views/topology/bundle.js (+1/-1)
docs/style-guide.rst (+6/-6)
test/test_app.js (+1/-1)
test/test_browser_app.js (+14/-14)
test/test_browser_charm_details.js (+10/-10)
test/test_browser_editorial.js (+8/-8)
test/test_browser_search_view.js (+4/-4)
test/test_browser_search_widget.js (+1/-1)
test/test_charm_panel.js (+1/-1)
test/test_charm_store.js (+61/-34)
test/test_charm_view.js (+1/-1)
test/test_conflict_ux.js (+1/-1)
test/test_environment_view.js (+2/-2)
test/test_ghost_inspector.js (+1/-1)
test/test_inspector_charm.js (+2/-2)
test/test_inspector_constraints.js (+1/-1)
test/test_inspector_overview.js (+1/-1)
test/test_inspector_settings.js (+1/-1)
test/test_model.js (+1/-1)
test/utils.js (+2/-2)
To merge this branch: bzr merge lp:~benji/juju-gui/reorganize-charmworld-api-part-A
Reviewer Review Type Date Requested Status
Juju GUI Hackers Pending
Review via email: mp+185591@code.launchpad.net

Description of the change

Factor out charmworld API helpers and rename

These changes are part of the move to adding v3 of the charmworld API.

https://codereview.appspot.com/13592047/

To post a comment you must log in.
Revision history for this message
Brad Crittenden (bac) wrote :
Revision history for this message
Richard Harding (rharding) wrote :

LGTM on the code. I'm not a huge fan of APIv2 as a name, but I guess we
don't use it much and it's clear.

Did not QA.

https://codereview.appspot.com/13592047/

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file 'app/app.js'
2--- app/app.js 2013-09-13 03:49:20 +0000
3+++ app/app.js 2013-09-13 20:06:29 +0000
4@@ -1356,8 +1356,8 @@
5 },
6 /**
7 @attribute store
8- @default Charmworld2
9- @type {Charmworld2}
10+ @default Y.juju.charmworld.APIv2
11+ @type {Y.juju.charmworld.APIv2}
12 */
13 store: {
14 /**
15@@ -1379,7 +1379,7 @@
16 } else {
17 cfg.apiHost = window.juju_config.charmworldURL;
18 }
19- return new Y.juju.Charmworld2(cfg);
20+ return new Y.juju.charmworld.APIv2(cfg);
21 }
22 },
23
24
25=== modified file 'app/models/charm.js'
26--- app/models/charm.js 2013-09-06 14:23:56 +0000
27+++ app/models/charm.js 2013-09-13 20:06:29 +0000
28@@ -386,7 +386,7 @@
29
30
31 /**
32- * Model to represent the Charms from the Charmworld2 Api.
33+ * Model to represent the Charms from the Charmworld API.
34 *
35 * @class BrowserCharm
36 * @extends {Y.Model}
37@@ -796,8 +796,9 @@
38 /**
39 * This attr is a mapper to the relations ATTR in the new API. It's
40 * provided for backwards compatibility with the original Charm model.
41- * This can be removed when Charmworld2 is the one true model used in
42- * all Juju Gui code.
43+ *
44+ * This can be removed when juju.charmworld is the one true provider of
45+ * models used in all Juju Gui code.
46 *
47 * @attribute provides
48 * @default undefined
49@@ -901,8 +902,8 @@
50 * This attr is a mapper to the relations ATTR in the new API. It's
51 * provided for backwards compatibility with the original Charm model.
52 *
53- * This can be removed when Charmworld2 is the one true model used in
54- * all Juju Gui code.
55+ * This can be removed when juju.charmworld is the one true provider of
56+ * models used in all Juju Gui code.
57 *
58 * @attribute requires
59 * @default undefined
60
61=== modified file 'app/models/model-controller.js'
62--- app/models/model-controller.js 2013-09-04 11:19:19 +0000
63+++ app/models/model-controller.js 2013-09-13 20:06:29 +0000
64@@ -197,7 +197,7 @@
65 Reference to the client charm store.
66
67 @attribute store
68- @type {Charmworld2}
69+ @type {Object}
70 @default undefined
71 */
72 store: {}
73
74=== modified file 'app/store/charm.js'
75--- app/store/charm.js 2013-09-12 16:42:21 +0000
76+++ app/store/charm.js 2013-09-13 20:06:29 +0000
77@@ -26,40 +26,40 @@
78 */
79
80 YUI.add('juju-charm-store', function(Y) {
81- var ns = Y.namespace('juju'),
82+ var juju = Y.namespace('juju'),
83+ ns = Y.namespace('juju.charmworld'),
84 models = Y.namespace('juju.models');
85
86- /**
87- * Api helper for the updated charmworld api v2.
88- *
89- * @class Charmworld2
90- * @extends {Base}
91- *
92- */
93- ns.Charmworld2 = Y.Base.create('charmworld2', Y.Base, [], {
94- _apiRoot: 'api/2',
95-
96- /**
97- * Send the actual request and handle response from the api.
98- *
99- * @method _makeRequest
100- * @param {Object} args any query params and arguments required.
101- * @private
102- *
103- */
104- _makeRequest: function(apiEndpoint, callbacks, args) {
105- // If we're in the noop state, just call the error callback.
106- if (this.get('noop')) {
107- callbacks.failure('noop failure');
108- return;
109- }
110-
111+ // Make Y.juju.charmworld refernce the "juju.charmworld" namespace.
112+ juju.charmworld = ns;
113+
114+ ns.ApiHelper = Y.Base.create('ApiHelper', Y.Base, [], {
115+
116+ /**
117+ Initializer for the class.
118+
119+ @method initializer
120+ @param {Object} cfg The configuration for the API interface.
121+ @return {undefined} Nothing.
122+ */
123+ initializer: function(cfg) {
124+ this.sendRequest = cfg.sendRequest;
125+ },
126+
127+ /**
128+ Send a request and handle the response from the API.
129+
130+ @method makeRequest
131+ @param {Object} args any query params and arguments required.
132+ @return {undefined} Nothing.
133+ */
134+ makeRequest: function(apiEndpoint, callbacks, args) {
135 // Any query string args need to be put onto the endpoint for calling.
136 if (args) {
137 apiEndpoint = apiEndpoint + '?' + Y.QueryString.stringify(args);
138 }
139
140- this.get('datasource').sendRequest({
141+ this.sendRequest({
142 request: apiEndpoint,
143 callback: {
144 success: function(io_request) {
145@@ -82,6 +82,74 @@
146 },
147
148 /**
149+ Normalize a charm name so we can request its full data. Charm lookup
150+ requires a very specific form of the charm identifier.
151+
152+ series/charm-revision
153+
154+ where revision can currently (API v2) be any numeric placeholder.
155+
156+ @method normalizeCharmId
157+ @param {String} charmId to normalize.
158+ @param {String} [defaultSeries='precise'] The series to use if none is
159+ specified in the charm ID.
160+ @return {String} normalized id.
161+ */
162+ normalizeCharmId: function(charmId, defaultSeries) {
163+ var result = charmId;
164+ if (/^(cs:|local:)/.exec(result)) {
165+ result = result.slice(result.indexOf(':') + 1);
166+ }
167+
168+ if (result.indexOf('/') === -1) {
169+ if (!defaultSeries) {
170+ console.warn('No default series provided when normalizing charm ' +
171+ 'ID. Using "precise".');
172+ defaultSeries = 'precise';
173+ }
174+ result = defaultSeries + '/' + result;
175+ }
176+ if (/\-(\d+|HEAD)/.exec(result) === null) {
177+ // Add in a revision placeholder
178+ result = result + '-1';
179+ }
180+ return result;
181+ }
182+
183+ }, {
184+ ATTRS: {
185+ }
186+ });
187+
188+ /**
189+ * Api helper for the charmworld API v2.
190+ *
191+ * @class APIv2
192+ * @extends {Base}
193+ *
194+ */
195+ ns.APIv2 = Y.Base.create('APIv2', Y.Base, [], {
196+ _apiRoot: 'api/2',
197+
198+ /**
199+ * Send the actual request and handle response from the api.
200+ *
201+ * @method _makeRequest
202+ * @param {Object} args any query params and arguments required.
203+ * @private
204+ *
205+ */
206+ _makeRequest: function(apiEndpoint, callbacks, args) {
207+ // If we're in the noop state, just call the error callback.
208+ if (this.get('noop')) {
209+ callbacks.failure('noop failure');
210+ return;
211+ }
212+ // Delegate the request making to the helper object.
213+ this.apiHelper.makeRequest(apiEndpoint, callbacks, args);
214+ },
215+
216+ /**
217 * Api call to fetch autocomplete suggestions based on the current term.
218 *
219 * @method autocomplete
220@@ -103,6 +171,7 @@
221 this._makeRequest(endpoint, callbacks, filters);
222 },
223
224+
225 /**
226 * Api call to fetch a charm's details.
227 *
228@@ -161,7 +230,7 @@
229 };
230 }
231 }
232- this._charm(this.normalizeCharmId(charmID, defaultSeries),
233+ this._charm(this.apiHelper.normalizeCharmId(charmID, defaultSeries),
234 callbacks, bindScope);
235 },
236
237@@ -185,41 +254,6 @@
238 },
239
240 /**
241- Normalize a charm name so we can request its full data. Charm lookup
242- requires a very specific form of the charm identifier.
243-
244- series/charm-revision
245-
246- where revision can currently (API v2) be any numeric placeholder.
247-
248- @method normalizeCharmId
249- @param {String} charmId to normalize.
250- @param {String} [defaultSeries='precise'] The series to use if none is
251- specified in the charm ID.
252- @return {String} normalized id.
253- */
254- normalizeCharmId: function(charmId, defaultSeries) {
255- var result = charmId;
256- if (/^(cs:|local:)/.exec(result)) {
257- result = result.slice(result.indexOf(':') + 1);
258- }
259-
260- if (result.indexOf('/') === -1) {
261- if (!defaultSeries) {
262- console.warn('No default series provided when normalizing charm ' +
263- 'ID. Using "precise".');
264- defaultSeries = 'precise';
265- }
266- result = defaultSeries + '/' + result;
267- }
268- if (/\-(\d+|HEAD)/.exec(result) === null) {
269- // Add in a revision placeholder
270- result = result + '-1';
271- }
272- return result;
273- },
274-
275- /**
276 Promises to return the latest charm ID for a given charm if a newer one
277 exists; this also caches the newer charm if one is available.
278
279@@ -498,7 +532,15 @@
280 * @type {Datasource}
281 *
282 */
283- datasource: {},
284+ datasource: {
285+ setter: function(datasource) {
286+ // Construct an API helper using the new datasource.
287+ this.apiHelper = new ns.ApiHelper({
288+ sendRequest: Y.bind(datasource.sendRequest, datasource)
289+ });
290+ return datasource;
291+ }
292+ },
293
294 /**
295 If there's no config we end up setting noop on the store so that tests
296
297=== modified file 'app/subapps/browser/browser.js'
298--- app/subapps/browser/browser.js 2013-09-06 16:22:23 +0000
299+++ app/subapps/browser/browser.js 2013-09-13 20:06:29 +0000
300@@ -1058,8 +1058,8 @@
301
302 /**
303 @attribute store
304- @default Charmworld2
305- @type {Charmworld2}
306+ @default juju.charmworld.APIv2
307+ @type {Object}
308 */
309 store: {},
310
311
312=== modified file 'app/subapps/browser/views/charm.js'
313--- app/subapps/browser/views/charm.js 2013-08-15 13:21:21 +0000
314+++ app/subapps/browser/views/charm.js 2013-09-13 20:06:29 +0000
315@@ -852,7 +852,7 @@
316 *
317 * @attribute store
318 * @default undefined
319- * @type {Charmworld2}
320+ * @type {Object}
321 *
322 */
323 store: {},
324
325=== modified file 'app/subapps/browser/views/charmresults.js'
326--- app/subapps/browser/views/charmresults.js 2013-08-07 18:19:54 +0000
327+++ app/subapps/browser/views/charmresults.js 2013-09-13 20:06:29 +0000
328@@ -182,11 +182,11 @@
329 renderTo: {},
330
331 /**
332- * The Charmworld2 Api store instance for loading content.
333+ * The Charmworld API store instance for loading content.
334 *
335 * @attribute store
336 * @default undefined
337- * @type {Charmworld2}
338+ * @type {Object}
339 */
340 store: {}
341 }
342
343=== modified file 'app/subapps/browser/views/view.js'
344--- app/subapps/browser/views/view.js 2013-08-23 13:21:48 +0000
345+++ app/subapps/browser/views/view.js 2013-09-13 20:06:29 +0000
346@@ -300,7 +300,7 @@
347 *
348 * @attribute store
349 * @default undefined
350- * @type {Charmworld2}
351+ * @type {Object}
352 *
353 */
354 store: {},
355
356=== modified file 'app/views/topology/bundle.js'
357--- app/views/topology/bundle.js 2013-09-06 00:26:54 +0000
358+++ app/views/topology/bundle.js 2013-09-13 20:06:29 +0000
359@@ -288,7 +288,7 @@
360 }
361 this.store = options.store;
362 if (!this.store) {
363- this.store = new juju.Charmworld2({});
364+ this.store = new juju.charmworld.APIv2({});
365 this._cleanups.push(this.store.destroy);
366 }
367 this.container = options.container;
368
369=== modified file 'docs/style-guide.rst'
370--- docs/style-guide.rst 2013-01-30 12:38:03 +0000
371+++ docs/style-guide.rst 2013-09-13 20:06:29 +0000
372@@ -189,12 +189,12 @@
373 Multi-line YUIDoc comment blocks like this will be needed::
374
375 /**
376- * Frob the thingy.
377- *
378- * @param {object} type How the thingy should be frobbed.
379- * @return {undefined} Side-effects only, eturns nothing.
380- * @method frob
381- */
382+ Frob the thingy.
383+
384+ @method frob
385+ @param {object} type How the thingy should be frobbed.
386+ @return {undefined} Side-effects only, eturns nothing.
387+ */
388
389 In this case, the type directive is the ``@method`` one. It is placed at
390 the end of the comment block, because it is little more than noise
391
392=== modified file 'test/test_app.js'
393--- test/test_app.js 2013-09-06 00:26:54 +0000
394+++ test/test_app.js 2013-09-13 20:06:29 +0000
395@@ -541,7 +541,7 @@
396 consoleEnabled: true,
397 user: 'admin',
398 password: 'admin',
399- store: new Y.juju.Charmworld2({})
400+ store: new Y.juju.charmworld.APIv2({})
401 });
402 app.showView(new Y.View());
403 // This simply walks through the hierarchy to show that all the
404
405=== modified file 'test/test_browser_app.js'
406--- test/test_browser_app.js 2013-09-06 15:06:53 +0000
407+++ test/test_browser_app.js 2013-09-13 20:06:29 +0000
408@@ -74,7 +74,7 @@
409 it('must correctly render the initial browser ui', function() {
410 var container = Y.one('#subapp-browser');
411 view = new FullScreen({
412- store: new Y.juju.Charmworld2({
413+ store: new Y.juju.charmworld.APIv2({
414 apiHost: 'http://localhost'
415 })
416 });
417@@ -107,7 +107,7 @@
418
419 it('must show the home icons when withHome is set', function() {
420 var container = Y.one('#subapp-browser'),
421- fakeStore = new Y.juju.Charmworld2({});
422+ fakeStore = new Y.juju.charmworld.APIv2({});
423
424 view = new FullScreen({
425 store: fakeStore,
426@@ -121,7 +121,7 @@
427
428 it('shows the home icons if the withHome is changed', function(done) {
429 var container = Y.one('#subapp-browser'),
430- fakeStore = new Y.juju.Charmworld2({});
431+ fakeStore = new Y.juju.charmworld.APIv2({});
432
433 view = new FullScreen({
434 store: fakeStore
435@@ -139,7 +139,7 @@
436
437 it('routes home when it catches a gohome event', function(done) {
438 var container = Y.one('#subapp-browser'),
439- fakeStore = new Y.juju.Charmworld2({});
440+ fakeStore = new Y.juju.charmworld.APIv2({});
441 view = new FullScreen({
442 store: fakeStore
443 });
444@@ -158,7 +158,7 @@
445
446 it('resets charmid and hash on search', function(done) {
447 var container = Y.one('#subapp-browser'),
448- fakeStore = new Y.juju.Charmworld2({});
449+ fakeStore = new Y.juju.charmworld.APIv2({});
450 view = new FullScreen({
451 charmID: 'precise/jenkins-13'
452 });
453@@ -281,7 +281,7 @@
454 var container = Y.one('#subapp-browser');
455 view = new Sidebar({
456 container: container,
457- store: new Y.juju.Charmworld2({
458+ store: new Y.juju.charmworld.APIv2({
459 apiHost: 'http://localhost'
460 })
461 });
462@@ -324,7 +324,7 @@
463 it('shows the home icon when instructed', function() {
464 var container = Y.one('#subapp-browser');
465 view = new Sidebar({
466- store: new Y.juju.Charmworld2({
467+ store: new Y.juju.charmworld.APIv2({
468 apiHost: 'http://localhost'
469 }),
470 withHome: true
471@@ -355,7 +355,7 @@
472
473 it('routes home when it catches a gohome event', function(done) {
474 var container = Y.one('#subapp-browser'),
475- fakeStore = new Y.juju.Charmworld2({});
476+ fakeStore = new Y.juju.charmworld.APIv2({});
477 view = new Sidebar({
478 store: fakeStore
479 });
480@@ -377,7 +377,7 @@
481
482 (function() {
483 describe('browser app', function() {
484- var Y, app, browser, Charmworld2, container, next;
485+ var Y, app, browser, CharmworldAPI, container, next;
486
487 before(function(done) {
488 Y = YUI(GlobalConfig).use(
489@@ -388,7 +388,7 @@
490 'juju-views',
491 'subapp-browser', function(Y) {
492 browser = Y.namespace('juju.subapps');
493- Charmworld2 = Y.namespace('juju').Charmworld2;
494+ CharmworldAPI = Y.namespace('juju').charmworld.APIv2;
495 next = function() {};
496 done();
497 });
498@@ -516,7 +516,7 @@
499
500 it('/charm/id routes to the default view correctly', function() {
501 app = new browser.Browser({
502- store: new Charmworld2({
503+ store: new CharmworldAPI({
504 'apiHost': 'http://localhost'
505 })
506 });
507@@ -534,7 +534,7 @@
508
509 it('/charm/id handles routes for new charms correctly', function() {
510 app = new browser.Browser({
511- store: new Charmworld2({
512+ store: new CharmworldAPI({
513 'apiHost': 'http://localhost'
514 })
515 });
516@@ -613,7 +613,7 @@
517
518 it('/charm/id router ignores other urls', function() {
519 app = new browser.Browser({
520- store: new Charmworld2({
521+ store: new CharmworldAPI({
522 'apiHost': 'http://localhost',
523 'noop': true
524 })
525@@ -642,7 +642,7 @@
526 editorialCleaned = false;
527
528 app = new browser.Browser({
529- store: new Charmworld2({
530+ store: new CharmworldAPI({
531 'apiHost': 'http://localhost',
532 'noop': true
533 })
534
535=== modified file 'test/test_browser_charm_details.js'
536--- test/test_browser_charm_details.js 2013-09-06 08:57:34 +0000
537+++ test/test_browser_charm_details.js 2013-09-13 20:06:29 +0000
538@@ -141,7 +141,7 @@
539 });
540
541 it('has sharing links', function() {
542- var fakeStore = new Y.juju.Charmworld2({});
543+ var fakeStore = new Y.juju.charmworld.APIv2({});
544 fakeStore.set('datasource', {
545 sendRequest: function(params) {
546 // Stubbing the server callback value
547@@ -255,7 +255,7 @@
548 });
549
550 it('should be able to display the readme content', function() {
551- var fakeStore = new Y.juju.Charmworld2({});
552+ var fakeStore = new Y.juju.charmworld.APIv2({});
553 fakeStore.set('datasource', {
554 sendRequest: function(params) {
555 // Stubbing the server callback value
556@@ -315,7 +315,7 @@
557
558
559 it('_addCharmEnvironment displays the config panel', function(done) {
560- var fakeStore = new Y.juju.Charmworld2({});
561+ var fakeStore = new Y.juju.charmworld.APIv2({});
562 fakeStore.iconpath = function() {
563 return 'charm icon url';
564 };
565@@ -345,7 +345,7 @@
566 });
567
568 it('should load a file when a hook is selected', function() {
569- var fakeStore = new Y.juju.Charmworld2({});
570+ var fakeStore = new Y.juju.charmworld.APIv2({});
571 fakeStore.set('datasource', {
572 sendRequest: function(params) {
573 // Stubbing the server callback value
574@@ -385,7 +385,7 @@
575 });
576
577 it('should be able to render markdown as html', function() {
578- var fakeStore = new Y.juju.Charmworld2({});
579+ var fakeStore = new Y.juju.charmworld.APIv2({});
580 fakeStore.set('datasource', {
581 sendRequest: function(params) {
582 // Stubbing the server callback value
583@@ -493,7 +493,7 @@
584 data.scores = null;
585 var fakedata = Y.JSON.stringify(data);
586
587- var fakeStore = new Y.juju.Charmworld2({});
588+ var fakeStore = new Y.juju.charmworld.APIv2({});
589 fakeStore.set('datasource', {
590 sendRequest: function(params) {
591 // Stubbing the server callback value
592@@ -841,7 +841,7 @@
593 // We don't want any files so we don't have to mock/load them.
594 data.files = [];
595
596- var fakeStore = new Y.juju.Charmworld2({});
597+ var fakeStore = new Y.juju.charmworld.APIv2({});
598 fakeStore.set('datasource', {
599 sendRequest: function(params) {
600 // Stubbing the server callback value
601@@ -887,7 +887,7 @@
602 // We don't want any files so we don't have to mock/load them.
603 data.files = [];
604
605- var fakeStore = new Y.juju.Charmworld2({});
606+ var fakeStore = new Y.juju.charmworld.APIv2({});
607 fakeStore.set('datasource', {
608 sendRequest: function(params) {
609 // Stubbing the server callback value
610@@ -922,7 +922,7 @@
611 // We don't want any files so we don't have to mock/load them.
612 data.files = [];
613
614- var fakeStore = new Y.juju.Charmworld2({});
615+ var fakeStore = new Y.juju.charmworld.APIv2({});
616 fakeStore.set('datasource', {
617 sendRequest: function(params) {
618 // Stubbing the server callback value
619@@ -973,7 +973,7 @@
620 // We don't want any files so we don't have to mock/load them.
621 data.files = [];
622
623- var fakeStore = new Y.juju.Charmworld2({});
624+ var fakeStore = new Y.juju.charmworld.APIv2({});
625 fakeStore.set('datasource', {
626 sendRequest: function(params) {
627 // Stubbing the server callback value
628
629=== modified file 'test/test_browser_editorial.js'
630--- test/test_browser_editorial.js 2013-08-23 13:02:58 +0000
631+++ test/test_browser_editorial.js 2013-09-13 20:06:29 +0000
632@@ -72,7 +72,7 @@
633 });
634
635 it('renders sidebar with hidden charms', function() {
636- fakeStore = new Y.juju.Charmworld2({});
637+ fakeStore = new Y.juju.charmworld.APIv2({});
638 fakeStore.set('datasource', {
639 sendRequest: function(params) {
640 // Stubbing the server callback value
641@@ -93,7 +93,7 @@
642
643 it('shows and hides an indicator', function(done) {
644 var hit = 0;
645- fakeStore = new Y.juju.Charmworld2({});
646+ fakeStore = new Y.juju.charmworld.APIv2({});
647 fakeStore.set('datasource', {
648 sendRequest: function(params) {
649 // Stubbing the server callback value
650@@ -120,7 +120,7 @@
651 });
652
653 it('renders fullscreen 14/22 charms hidden', function() {
654- fakeStore = new Y.juju.Charmworld2({});
655+ fakeStore = new Y.juju.charmworld.APIv2({});
656 fakeStore.set('datasource', {
657 sendRequest: function(params) {
658 // Stubbing the server callback value
659@@ -141,7 +141,7 @@
660 });
661
662 it('clicking a charm navigates for fullscreen', function(done) {
663- fakeStore = new Y.juju.Charmworld2({});
664+ fakeStore = new Y.juju.charmworld.APIv2({});
665 fakeStore.set('datasource', {
666 sendRequest: function(params) {
667 // Stubbing the server callback value
668@@ -169,7 +169,7 @@
669 });
670
671 it('clicking a charm navigates for sidebar', function(done) {
672- fakeStore = new Y.juju.Charmworld2({});
673+ fakeStore = new Y.juju.charmworld.APIv2({});
674 fakeStore.set('datasource', {
675 sendRequest: function(params) {
676 // Stubbing the server callback value
677@@ -196,7 +196,7 @@
678 });
679
680 it('setting the activeID marks the div active', function() {
681- fakeStore = new Y.juju.Charmworld2({});
682+ fakeStore = new Y.juju.charmworld.APIv2({});
683 fakeStore.set('datasource', {
684 sendRequest: function(params) {
685 // Stubbing the server callback value
686@@ -217,7 +217,7 @@
687 });
688
689 it('unsetting the activeID will remove the active markings', function() {
690- fakeStore = new Y.juju.Charmworld2({});
691+ fakeStore = new Y.juju.charmworld.APIv2({});
692 fakeStore.set('datasource', {
693 sendRequest: function(params) {
694 // Stubbing the server callback value
695@@ -255,7 +255,7 @@
696 });
697
698 it('uses passed in cache data if available', function() {
699- fakeStore = new Y.juju.Charmworld2({});
700+ fakeStore = new Y.juju.charmworld.APIv2({});
701 fakeStore.set('datasource', {
702 sendRequest: function(params) {
703 // Stubbing the server callback value
704
705=== modified file 'test/test_browser_search_view.js'
706--- test/test_browser_search_view.js 2013-09-05 20:04:58 +0000
707+++ test/test_browser_search_view.js 2013-09-13 20:06:29 +0000
708@@ -53,7 +53,7 @@
709 //
710 // Create monkeypatched store to verify right method is called.
711 apiURL = '';
712- var fakeStore = new Y.juju.Charmworld2({});
713+ var fakeStore = new Y.juju.charmworld.APIv2({});
714 var sampleData = {
715 result: [{
716 charm: {
717@@ -161,7 +161,7 @@
718 }
719 }]
720 };
721- var fakeStore = new Y.juju.Charmworld2({});
722+ var fakeStore = new Y.juju.charmworld.APIv2({});
723 fakeStore.set('datasource', {
724 sendRequest: function(params) {
725 // Stubbing the server callback value
726@@ -205,7 +205,7 @@
727 }
728 }]
729 };
730- var fakeStore = new Y.juju.Charmworld2({});
731+ var fakeStore = new Y.juju.charmworld.APIv2({});
732 fakeStore.set('datasource', {
733 sendRequest: function(params) {
734 // Stubbing the server callback value
735@@ -249,7 +249,7 @@
736 }
737 }]
738 };
739- var fakeStore = new Y.juju.Charmworld2({});
740+ var fakeStore = new Y.juju.charmworld.APIv2({});
741 fakeStore.set('datasource', {
742 sendRequest: function(params) {
743 // Stubbing the server callback value
744
745=== modified file 'test/test_browser_search_widget.js'
746--- test/test_browser_search_widget.js 2013-09-06 08:57:34 +0000
747+++ test/test_browser_search_widget.js 2013-09-13 20:06:29 +0000
748@@ -203,7 +203,7 @@
749 cleanIconHelper = utils.stubCharmIconPath();
750
751 // We need a valid store instance to send back the data.
752- fakeStore = new Y.juju.Charmworld2({});
753+ fakeStore = new Y.juju.charmworld.APIv2({});
754 fakeStore.set('datasource', {
755 sendRequest: function(params) {
756 // Stubbing the server callback value
757
758=== modified file 'test/test_charm_panel.js'
759--- test/test_charm_panel.js 2013-09-06 00:26:54 +0000
760+++ test/test_charm_panel.js 2013-09-13 20:06:29 +0000
761@@ -129,7 +129,7 @@
762 }
763 };
764 // Mock the charm store.
765- store = new juju.Charmworld2({
766+ store = new juju.charmworld.APIv2({
767 datasource: {
768 sendRequest: function(params) {
769 params.callback.success({
770
771=== modified file 'test/test_charm_store.js'
772--- test/test_charm_store.js 2013-09-12 17:06:27 +0000
773+++ test/test_charm_store.js 2013-09-13 20:06:29 +0000
774@@ -21,7 +21,8 @@
775 (function() {
776
777 describe('Charmworld API v2 interface', function() {
778- var Y, models, conn, env, app, container, data, juju, utils, hostname;
779+ var Y, models, conn, env, app, container, data, juju, utils, charmworld,
780+ hostname;
781
782
783 before(function(done) {
784@@ -31,6 +32,7 @@
785 'juju-tests-utils',
786 function(Y) {
787 juju = Y.namespace('juju');
788+ charmworld = Y.namespace('juju.charmworld');
789 models = Y.namespace('juju.models');
790 utils = Y.namespace('juju-tests').utils;
791 done();
792@@ -42,20 +44,20 @@
793 });
794
795 it('constructs the api url correctly based on apiHost', function() {
796- var api = new Y.juju.Charmworld2({apiHost: hostname}),
797+ var api = new charmworld.APIv2({apiHost: hostname}),
798 ds = api.get('datasource');
799
800 ds.get('source').should.eql(hostname + 'api/2/');
801
802 // And it should work without a trailing / as well.
803 hostname = hostname.slice(0, -1);
804- api = new Y.juju.Charmworld2({apiHost: hostname});
805+ api = new charmworld.APIv2({apiHost: hostname});
806 ds = api.get('datasource');
807 ds.get('source').should.eql(hostname + '/api/2/');
808 });
809
810 it('handles loading interesting content correctly', function(done) {
811- var api = new Y.juju.Charmworld2({apiHost: hostname}),
812+ var api = new charmworld.APIv2({apiHost: hostname}),
813 data = [];
814
815 data.push({responseText: Y.JSON.stringify({summary: 'wowza'})});
816@@ -73,7 +75,7 @@
817 });
818
819 it('handles searching correctly', function(done) {
820- var api = new Y.juju.Charmworld2({apiHost: hostname}),
821+ var api = new charmworld.APIv2({apiHost: hostname}),
822 data = [],
823 url;
824 data.push({responseText: Y.JSON.stringify({name: 'foo'})});
825@@ -100,7 +102,7 @@
826 });
827
828 it('constructs filepaths correctly', function() {
829- var api = new Y.juju.Charmworld2({apiHost: hostname});
830+ var api = new charmworld.APIv2({apiHost: hostname});
831 var iconPath = api.filepath('precise/mysql-1', 'icon.svg');
832 assert.equal(
833 iconPath,
834@@ -108,7 +110,7 @@
835 });
836
837 it('constructs cateogry icon paths correctly', function() {
838- var api = new Y.juju.Charmworld2({apiHost: hostname});
839+ var api = new charmworld.APIv2({apiHost: hostname});
840
841 var iconPath = api.categoryIconPath('app-servers');
842 assert.equal(
843@@ -117,7 +119,7 @@
844 });
845
846 it('makes charm requests to correct URL', function(done) {
847- var api = new Y.juju.Charmworld2({apiHost: hostname});
848+ var api = new charmworld.APIv2({apiHost: hostname});
849
850 api._makeRequest = function(endpoint, callbacks, filters) {
851 assert.equal(endpoint, 'charm/CHARM-ID');
852@@ -128,7 +130,7 @@
853 });
854
855 it('can use a cache to avoid requesting charm data', function(done) {
856- var api = new Y.juju.Charmworld2({apiHost: hostname});
857+ var api = new charmworld.APIv2({apiHost: hostname});
858
859 var should_not_happen = function() {
860 assert.isTrue(false, 'Oops, this should not have been called.');
861@@ -156,7 +158,7 @@
862 });
863
864 it('will make a request on a cache miss', function(done) {
865- var api = new Y.juju.Charmworld2({apiHost: hostname});
866+ var api = new charmworld.APIv2({apiHost: hostname});
867
868 var should_not_happen = function() {
869 assert.isTrue(false, 'Oops, this should not have been called.');
870@@ -188,7 +190,7 @@
871
872 it('makes autocomplete requests to correct URL', function(done) {
873 var noop = function() {};
874- var api = new Y.juju.Charmworld2({apiHost: hostname});
875+ var api = new charmworld.APIv2({apiHost: hostname});
876
877 api._makeRequest = function(endpoint, callbacks, filters) {
878 assert.equal(endpoint, 'charms');
879@@ -200,7 +202,7 @@
880
881 it('makes autocomplete requests with right query flag', function(done) {
882 var noop = function() {};
883- var api = new Y.juju.Charmworld2({apiHost: hostname});
884+ var api = new charmworld.APIv2({apiHost: hostname});
885
886 api._makeRequest = function(endpoint, callbacks, filters) {
887 assert.equal(filters.autocomplete, 'true');
888@@ -211,47 +213,29 @@
889 });
890
891 it('constructs iconpaths correctly', function() {
892- var api = new Y.juju.Charmworld2({apiHost: hostname});
893+ var api = new charmworld.APIv2({apiHost: hostname});
894
895 var iconPath = api.iconpath('precise/mysql-1');
896 assert.equal(iconPath, hostname + 'api/2/charm/precise/mysql-1/icon.svg');
897 });
898
899 it('constructs an icon path for local charms', function() {
900- var api = new Y.juju.Charmworld2({apiHost: hostname});
901+ var api = new charmworld.APIv2({apiHost: hostname});
902
903 var iconPath = api.iconpath('local:precise/mysql-1');
904 assert.equal(iconPath, hostname + 'static/img/charm_160.svg');
905 });
906
907 it('splits the charm id to remove cs: when necessary', function() {
908- var api = new Y.juju.Charmworld2({apiHost: hostname});
909+ var api = new charmworld.APIv2({apiHost: hostname});
910 var iconPath = api.iconpath('cs:precise/mysql-1');
911 assert.equal(iconPath, hostname + 'api/2/charm/precise/mysql-1/icon.svg');
912 });
913
914- it('can normalize charm names for lookup', function() {
915- var api = new Y.juju.Charmworld2({apiHost: hostname});
916- assert.equal(api.normalizeCharmId('wordpress', 'precise'),
917- 'precise/wordpress-1');
918- assert.equal(api.normalizeCharmId('precise/wordpress', 'precise'),
919- 'precise/wordpress-1');
920- assert.equal(api.normalizeCharmId('precise/wordpress'),
921- 'precise/wordpress-1');
922- assert.equal(api.normalizeCharmId('precise/wordpress-10'),
923- 'precise/wordpress-10');
924- assert.equal(api.normalizeCharmId('cs:precise/wordpress-10'),
925- 'precise/wordpress-10');
926- assert.equal(api.normalizeCharmId('precise/wordpress-HEAD'),
927- 'precise/wordpress-HEAD');
928- assert.equal(api.normalizeCharmId('cs:precise/wordpress-HEAD'),
929- 'precise/wordpress-HEAD');
930- });
931-
932 it('can fetch a charm via a promise', function(done) {
933 // The "promiseCharm" method is just a promise-wrapped version of the
934 // "charm" method.
935- var api = new Y.juju.Charmworld2({apiHost: hostname});
936+ var api = new charmworld.APIv2({apiHost: hostname});
937 var DATA = 'DATA';
938 var CHARM = 'CHARM';
939 api.charm = function(charmID, callbacks) {
940@@ -292,4 +276,47 @@
941
942 });
943
944+ describe('Charmworld API Helper', function() {
945+ var Y, models, conn, env, app, container, data, juju, utils, charmworld,
946+ hostname;
947+
948+
949+ before(function(done) {
950+ Y = YUI(GlobalConfig).use(
951+ 'datasource-local', 'json-stringify', 'juju-charm-store',
952+ 'datasource-io', 'io', 'array-extras', 'juju-charm-models',
953+ 'juju-tests-utils',
954+ function(Y) {
955+ juju = Y.namespace('juju');
956+ charmworld = Y.namespace('juju.charmworld');
957+ models = Y.namespace('juju.models');
958+ utils = Y.namespace('juju-tests').utils;
959+ done();
960+ });
961+ });
962+
963+ beforeEach(function() {
964+ hostname = 'http://charmworld.example/';
965+ });
966+
967+ it('can normalize charm names for lookup', function() {
968+ var apiHelper = new charmworld.ApiHelper({});
969+ assert.equal(apiHelper.normalizeCharmId('wordpress', 'precise'),
970+ 'precise/wordpress-1');
971+ assert.equal(apiHelper.normalizeCharmId('precise/wordpress', 'precise'),
972+ 'precise/wordpress-1');
973+ assert.equal(apiHelper.normalizeCharmId('precise/wordpress'),
974+ 'precise/wordpress-1');
975+ assert.equal(apiHelper.normalizeCharmId('precise/wordpress-10'),
976+ 'precise/wordpress-10');
977+ assert.equal(apiHelper.normalizeCharmId('cs:precise/wordpress-10'),
978+ 'precise/wordpress-10');
979+ assert.equal(apiHelper.normalizeCharmId('precise/wordpress-HEAD'),
980+ 'precise/wordpress-HEAD');
981+ assert.equal(apiHelper.normalizeCharmId('cs:precise/wordpress-HEAD'),
982+ 'precise/wordpress-HEAD');
983+ });
984+
985+ });
986+
987 })();
988
989=== modified file 'test/test_charm_view.js'
990--- test/test_charm_view.js 2013-09-06 00:26:54 +0000
991+++ test/test_charm_view.js 2013-09-13 20:06:29 +0000
992@@ -90,7 +90,7 @@
993 container = Y.Node.create('<div id="test-container" />');
994 Y.one('#main').append(container);
995 CharmView = juju.views.charm;
996- fakeStore = new Y.juju.Charmworld2({});
997+ fakeStore = new Y.juju.charmworld.APIv2({});
998 fakeStore.set('datasource', {
999 sendRequest: function(params) {
1000 // Stubbing the server callback value
1001
1002=== modified file 'test/test_conflict_ux.js'
1003--- test/test_conflict_ux.js 2013-09-13 03:25:47 +0000
1004+++ test/test_conflict_ux.js 2013-09-13 20:06:29 +0000
1005@@ -82,7 +82,7 @@
1006 ['unit', 'add', {id: 'mediawiki/0', agent_state: 'pending'}]
1007 ]}});
1008
1009- var fakeStore = new Y.juju.Charmworld2({});
1010+ var fakeStore = new Y.juju.charmworld.APIv2({});
1011 fakeStore.iconpath = function() {
1012 return 'charm icon url';
1013 };
1014
1015=== modified file 'test/test_environment_view.js'
1016--- test/test_environment_view.js 2013-09-06 00:26:54 +0000
1017+++ test/test_environment_view.js 2013-09-13 20:06:29 +0000
1018@@ -113,7 +113,7 @@
1019 env = juju.newEnvironment({conn: conn});
1020 env.connect();
1021 conn.open();
1022- fakeStore = new Y.juju.Charmworld2({});
1023+ fakeStore = new Y.juju.charmworld.APIv2({});
1024 fakeStore.iconpath = function() {
1025 return 'charm icon url';
1026 };
1027@@ -1195,7 +1195,7 @@
1028 });
1029
1030 it('sets the default icon for local charms without an icon', function() {
1031- var iconFakeStore = new Y.juju.Charmworld2({
1032+ var iconFakeStore = new Y.juju.charmworld.APIv2({
1033 apiHost: 'http://localhost'
1034 });
1035 var services = new models.ServiceList();
1036
1037=== modified file 'test/test_ghost_inspector.js'
1038--- test/test_ghost_inspector.js 2013-09-12 12:36:25 +0000
1039+++ test/test_ghost_inspector.js 2013-09-13 20:06:29 +0000
1040@@ -69,7 +69,7 @@
1041 // Create a ghost service with the fake charm.
1042 service = db.services.ghostService(charm);
1043
1044- var fakeStore = new Y.juju.Charmworld2({});
1045+ var fakeStore = new Y.juju.charmworld.APIv2({});
1046 fakeStore.iconpath = function(id) {
1047 return '/icon/' + id;
1048 };
1049
1050=== modified file 'test/test_inspector_charm.js'
1051--- test/test_inspector_charm.js 2013-08-27 18:06:51 +0000
1052+++ test/test_inspector_charm.js 2013-09-13 20:06:29 +0000
1053@@ -68,7 +68,7 @@
1054 testContainer = utils.makeContainer();
1055 testContainer.setHTML('<div class="left-breakout"></div>');
1056
1057- fakeStore = new Y.juju.Charmworld2({});
1058+ fakeStore = new Y.juju.charmworld.APIv2({});
1059 fakeStore.set('datasource', {
1060 sendRequest: function(params) {
1061 // Stubbing the server callback value
1062@@ -107,7 +107,7 @@
1063 testContainer = utils.makeContainer();
1064 testContainer.setHTML('<div class="left-breakout"></div>');
1065
1066- fakeStore = new Y.juju.Charmworld2({});
1067+ fakeStore = new Y.juju.charmworld.APIv2({});
1068 var cache = new Y.juju.models.BrowserCharmList();
1069 var charm = new Y.juju.models.BrowserCharm(data.charm);
1070 charm.set('cached', true);
1071
1072=== modified file 'test/test_inspector_constraints.js'
1073--- test/test_inspector_constraints.js 2013-09-11 15:40:06 +0000
1074+++ test/test_inspector_constraints.js 2013-09-13 20:06:29 +0000
1075@@ -86,7 +86,7 @@
1076 var conn = new utils.SocketStub();
1077 var db = new models.Database();
1078 var service = makeService(db);
1079- var fakeStore = new Y.juju.Charmworld2({});
1080+ var fakeStore = new Y.juju.charmworld.APIv2({});
1081 fakeStore.iconpath = function() {
1082 return 'charm icon url';
1083 };
1084
1085=== modified file 'test/test_inspector_overview.js'
1086--- test/test_inspector_overview.js 2013-09-13 18:06:31 +0000
1087+++ test/test_inspector_overview.js 2013-09-13 20:06:29 +0000
1088@@ -109,7 +109,7 @@
1089 ['unit', 'add', {id: 'mediawiki/1', agent_state: 'pending'}],
1090 ['unit', 'add', {id: 'mediawiki/2', agent_state: 'pending'}]
1091 ]}});
1092- var fakeStore = new Y.juju.Charmworld2({});
1093+ var fakeStore = new Y.juju.charmworld.APIv2({});
1094 fakeStore.iconpath = function(id) {
1095 return '/icon/' + id;
1096 };
1097
1098=== modified file 'test/test_inspector_settings.js'
1099--- test/test_inspector_settings.js 2013-09-12 19:56:59 +0000
1100+++ test/test_inspector_settings.js 2013-09-13 20:06:29 +0000
1101@@ -93,7 +93,7 @@
1102 ['unit', 'add', {id: 'mediawiki/2', agent_state: 'pending'}]
1103 ]}});
1104 }
1105- var fakeStore = new Y.juju.Charmworld2({});
1106+ var fakeStore = new Y.juju.charmworld.APIv2({});
1107 fakeStore.iconpath = function() {
1108 return 'charm icon url';
1109 };
1110
1111=== modified file 'test/test_model.js'
1112--- test/test_model.js 2013-09-11 20:39:45 +0000
1113+++ test/test_model.js 2013-09-13 20:06:29 +0000
1114@@ -488,7 +488,7 @@
1115 conn.open();
1116 container = Y.Node.create('<div id="test" class="container"></div>');
1117 data = [];
1118- fakeStore = new Y.juju.Charmworld2({});
1119+ fakeStore = new Y.juju.charmworld.APIv2({});
1120 fakeStore.set('datasource', {
1121 sendRequest: function(params) {
1122 params.callback.success({
1123
1124=== modified file 'test/utils.js'
1125--- test/utils.js 2013-08-21 15:47:36 +0000
1126+++ test/utils.js 2013-09-13 20:06:29 +0000
1127@@ -139,9 +139,9 @@
1128
1129 makeFakeStore: function(cache) {
1130 var modellist = cache;
1131- var fakeStore = new Y.juju.Charmworld2({});
1132+ var fakeStore = new Y.juju.charmworld.APIv2({});
1133 fakeStore.charm = function(store_id, callbacks, bindscope, cache) {
1134- store_id = this.normalizeCharmId(store_id, 'precise');
1135+ store_id = this.apiHelper.normalizeCharmId(store_id, 'precise');
1136 var charmName = store_id.split('/')[1];
1137 charmName = charmName.split('-', 1);
1138 if (charmName in jujuTests.utils._cached_charms) {

Subscribers

People subscribed via source and target branches