diff --git a/lib/canvas/require_js.rb b/lib/canvas/require_js.rb
index dd6e1ad945c..2214cac0729 100644
--- a/lib/canvas/require_js.rb
+++ b/lib/canvas/require_js.rb
@@ -64,7 +64,8 @@ module Canvas
:use => 'vendor/use',
:uploadify => '../flash/uploadify/jquery.uploadify-3.1.min',
'ic-menu' => 'vendor/ic-menu/dist/main.amd',
- 'ic-dialog' => 'vendor/ic-dialog/dist/main.amd.js',
+ 'ic-dialog' => 'vendor/ic-dialog/dist/main.amd',
+ 'ic-ajax' => 'vendor/ic-ajax/main',
}.update(cache_busting ? cache_busting_paths : {}).update(plugin_paths).update(Canvas::RequireJs::PluginExtension.paths).to_json.gsub(/([,{])/, "\\1\n ")
end
diff --git a/loom/generators/app.js b/loom/generators/app.js
index 33383f3e9f3..df9a5adcc8d 100644
--- a/loom/generators/app.js
+++ b/loom/generators/app.js
@@ -18,7 +18,8 @@ exports.templates = [
'new_app/config/app.coffee.hbs',
'new_app/config/routes.coffee.hbs',
'new_app/templates/application.hbs.hbs',
- 'new_app/tests/app.coffee.hbs',
+ 'new_app/routes/route.coffee.hbs',
+ 'new_app/tests/start_app.coffee.hbs',
'new_app/tests/app.spec.coffee.hbs'
];
@@ -28,7 +29,8 @@ exports.savePath = function(template, env) {
'new_app/config/app.coffee.hbs': 'app/coffeescripts/ember/'+env.appName+'/config/app.coffee',
'new_app/config/routes.coffee.hbs': 'app/coffeescripts/ember/'+env.appName+'/config/routes.coffee',
'new_app/templates/application.hbs.hbs': 'app/coffeescripts/ember/'+env.appName+'/templates/'+env.appName+'.hbs',
- 'new_app/tests/app.coffee.hbs': 'app/coffeescripts/ember/'+env.appName+'/tests/app.coffee',
+ 'new_app/routes/route.coffee.hbs': 'app/coffeescripts/ember/'+env.appName+'/routes/'+env.appName+'_route.coffee',
+ 'new_app/tests/start_app.coffee.hbs': 'app/coffeescripts/ember/'+env.appName+'/tests/start_app.coffee',
'new_app/tests/app.spec.coffee.hbs': 'app/coffeescripts/ember/'+env.appName+'/tests/app.spec.coffee'
}[template];
};
diff --git a/loom/templates/new_app/routes/route.coffee.hbs b/loom/templates/new_app/routes/route.coffee.hbs
new file mode 100644
index 00000000000..cf96c93c156
--- /dev/null
+++ b/loom/templates/new_app/routes/route.coffee.hbs
@@ -0,0 +1,8 @@
+define ['ember', 'ic-ajax'], (Ember, ajax) ->
+
+ FakeRoute = Ember.Route.extend
+
+ model: ->
+ ajax('/api/v1/users/self/activity_stream').then ({response}) ->
+ response
+
diff --git a/loom/templates/new_app/templates/application.hbs.hbs b/loom/templates/new_app/templates/application.hbs.hbs
index baff3443ef3..a19e5d32448 100644
--- a/loom/templates/new_app/templates/application.hbs.hbs
+++ b/loom/templates/new_app/templates/application.hbs.hbs
@@ -1,2 +1,9 @@
HELLO!
+
+ \{{#each}}
+ - \{{title}}
+ \{{/each}}
+
+
+
diff --git a/loom/templates/new_app/tests/app.coffee.hbs b/loom/templates/new_app/tests/app.coffee.hbs
deleted file mode 100644
index 71a0fcd1f7d..00000000000
--- a/loom/templates/new_app/tests/app.coffee.hbs
+++ /dev/null
@@ -1,14 +0,0 @@
-define ['../main'], (Application) ->
- App = Application.create
- LOG_ACTIVE_GENERATION: yes
- LOG_MODULE_RESOLVER: yes
- LOG_TRANSITIONS: yes
- LOG_TRANSITIONS_INTERNAL: yes
- LOG_VIEW_LOOKUPS: yes
- rootElement: '#fixtures'
- history: 'none'
- App.setupForTesting()
- App.injectTestHelpers()
- App.advanceReadiness()
- App
-
diff --git a/loom/templates/new_app/tests/app.spec.coffee.hbs b/loom/templates/new_app/tests/app.spec.coffee.hbs
index fc9f665362b..a080b6fd313 100644
--- a/loom/templates/new_app/tests/app.spec.coffee.hbs
+++ b/loom/templates/new_app/tests/app.spec.coffee.hbs
@@ -1,11 +1,28 @@
-define ['./app', 'ember'], (App, Ember) ->
+define [
+ './start_app'
+ 'ember'
+ 'ic-ajax'
+], (startApp, Ember, ajax) ->
- module '{{appName}}', ->
+ App = null
+
+ ajax.defineFixture '/api/v1/users/self/activity_stream',
+ response: [
+ {title: 'foo'}
+ {title: 'bar'}
+ ]
+ jqXHR: {}
+ textStatus: ''
+
+ module '{{appName}}',
setup: ->
- App.reset()
- Ember.run(App, App.advanceReadiness)
+ App = startApp()
+ teardown: ->
+ Ember.run App, 'destroy'
- test 'says hello', ->
- visit('/').then ->
- equal(find('h1').html().trim(), 'HELLO!')
+ test 'fetches and renders stream items', ->
+ controller = App.__container__.lookup('controller:{{appName}}')
+ equal controller.objectAt(0).title, 'foo'
+ equal controller.objectAt(1).title, 'bar'
+ equal find('h1').html().trim(), 'HELLO!'
diff --git a/loom/templates/new_app/tests/start_app.coffee.hbs b/loom/templates/new_app/tests/start_app.coffee.hbs
new file mode 100644
index 00000000000..6e038bbb03d
--- /dev/null
+++ b/loom/templates/new_app/tests/start_app.coffee.hbs
@@ -0,0 +1,19 @@
+define ['../main'], (Application) ->
+ startApp = ->
+ App = null
+ Ember.run.join ->
+ App = Application.create
+ LOG_ACTIVE_GENERATION: yes
+ LOG_MODULE_RESOLVER: yes
+ LOG_TRANSITIONS: yes
+ LOG_TRANSITIONS_INTERNAL: yes
+ LOG_VIEW_LOOKUPS: yes
+ rootElement: '#fixtures'
+ App.Router.reopen history: 'none'
+ App.setupForTesting()
+ App.injectTestHelpers()
+ App.advanceReadiness()
+ window.App = App
+ App
+
+
diff --git a/public/javascripts/vendor/ic-ajax/main.js b/public/javascripts/vendor/ic-ajax/main.js
new file mode 100644
index 00000000000..6358527c7ca
--- /dev/null
+++ b/public/javascripts/vendor/ic-ajax/main.js
@@ -0,0 +1,114 @@
+/*!
+ * ic-ajax
+ *
+ * - please see license at https://github.com/instructure/ember-ajax
+ * - inspired by discourse ajax: https://github.com/discourse/discourse/blob/master/app/assets/javascripts/discourse/mixins/ajax.js#L19
+ */
+
+;(function(root, factory) {
+ if (typeof define === 'function' && define.amd) {
+ define(['ember'], function(Ember) { return factory(Ember); });
+ } else if (typeof exports === 'object') {
+ module.exports = factory(require('ember'));
+ } else {
+ root.ic = root.ic || {};
+ root.ic.ajax = factory(Ember);
+ }
+}(this, function(Ember) {
+
+ /*
+ * jQuery.ajax wrapper, supports the same signature except providing
+ * `success` and `error` handlers will throw an error (use promises
+ * instead).
+ */
+
+ var ajax = function() {
+ return makePromise(parseArgs.apply(null, arguments));
+ };
+
+ /*
+ * Defines a fixture that will be used instead of an actual ajax
+ * request to a given url. This is useful for testing, allowing you to
+ * stub out responses your application will send without requiring
+ * libraries like sinon or mockjax, etc.
+ *
+ * For example:
+ *
+ * ajax.defineFixture('/self', {
+ * response: { firstName: 'Ryan', lastName: 'Florence' },
+ * textStatus: 'success'
+ * jqXHR: {}
+ * });
+ *
+ * @param {String} url
+ * @param {Object} fixture
+ */
+ ajax.defineFixture = function(url, fixture) {
+ ajax.FIXTURES = ajax.FIXTURES || {};
+ ajax.FIXTURES[url] = fixture;
+ };
+
+ /*
+ * Looks up a fixture by url.
+ *
+ * @param {String} url
+ */
+
+ ajax.lookupFixture = function(url) {
+ return ajax.FIXTURES && ajax.FIXTURES[url];
+ };
+
+ function makePromise(settings) {
+ return new Ember.RSVP.Promise(function(resolve, reject) {
+ var fixture = ajax.lookupFixture(settings.url);
+ if (fixture) {
+ return resolve(fixture);
+ }
+ settings.success = makeSuccess(resolve, reject);
+ settings.error = makeError(resolve, reject);
+ Ember.$.ajax(settings);
+ });
+ };
+
+ function parseArgs() {
+ var settings = {};
+ if (arguments.length === 1) {
+ if (typeof arguments[0] === "string") {
+ settings.url = arguments[0];
+ } else {
+ settings = arguments[0];
+ }
+ } else if (arguments.length === 2) {
+ settings = arguments[1];
+ settings.url = arguments[0];
+ }
+ if (settings.success || settings.error) {
+ throw new Error("ajax should use promises, received 'success' or 'error' callback");
+ }
+ return settings;
+ }
+
+ function makeSuccess(resolve, reject) {
+ return function(response, textStatus, jqXHR) {
+ Ember.run(null, resolve, {
+ response: response,
+ textStatus: textStatus,
+ jqXHR: jqXHR
+ });
+ }
+ }
+
+ function makeError(resolve, reject) {
+ return function(jqXHR, textStatus, errorThrown) {
+ Ember.run(null, reject, {
+ jqXHR: jqXHR,
+ textStatus: textStatus,
+ errorThrown: errorThrown
+ });
+ };
+ }
+
+ return ajax;
+
+}));
+