diff --git a/.jshintrc b/.jshintrc index f626a1a2..2052e610 100644 --- a/.jshintrc +++ b/.jshintrc @@ -1,5 +1,6 @@ { "predef": [ + "server", "document", "window", "-Promise", diff --git a/app/adapters/application.js b/app/adapters/application.js index cdd17038..e93e1c4a 100644 --- a/app/adapters/application.js +++ b/app/adapters/application.js @@ -2,7 +2,9 @@ import DS from 'ember-data'; import config from '../config/environment'; export default DS.RESTAdapter.extend({ - host:'https://api.github.com', + + host: config.host, + headers: Em.computed('session.token', function() { var token = this.get('session.token') || config.TMP_TORII_TOKEN; if (token) { diff --git a/app/components/dummy-demo-app.js b/app/components/dummy-demo-app.js index b95247a0..dd2de429 100644 --- a/app/components/dummy-demo-app.js +++ b/app/components/dummy-demo-app.js @@ -1,8 +1,9 @@ +import Ember from 'ember'; import ResizeMixin from 'ember-twiddle/lib/resize-mixin'; import config from '../config/environment'; -export default Em.Component.extend(ResizeMixin, { +export default Ember.Component.extend(ResizeMixin, { iframeId: 'dummy-content-iframe', didReceiveAttrs: function() { diff --git a/app/mirage/config.js b/app/mirage/config.js new file mode 100644 index 00000000..6a8624af --- /dev/null +++ b/app/mirage/config.js @@ -0,0 +1,12 @@ +export default function() {} + +/* + * Only loaded during tests + */ +export function testConfig() { + + this.get('/gists/:id', function(db, request) { + let id = request.params.id; + return db.gists.find(id); + }); +} diff --git a/app/mirage/factories/gist-file.js b/app/mirage/factories/gist-file.js new file mode 100644 index 00000000..457cebc8 --- /dev/null +++ b/app/mirage/factories/gist-file.js @@ -0,0 +1,53 @@ +/** + * This is a factory definition for a gist file + */ +import Mirage/*, {faker} */ from 'ember-cli-mirage'; + +export default Mirage.Factory.extend({ + type() { + let extension = this.filename.substring(this.filename.lastIndexOf("."), this.filename.length); + switch (extension) { + case ".hbs": + return "text/plain"; + case ".css": + return "text/css"; + case ".js": + return "application/javascript"; + case ".json": + return "application/json"; + } + }, + language() { + let extension = this.filename.substring(this.filename.lastIndexOf("."), this.filename.length); + switch (extension) { + case ".hbs": + return "Handlebars"; + case ".css": + return "CSS"; + case ".js": + return "JavaScript"; + case ".json": + return "JSON"; + } + }, + raw_url() { + return `https://gist.githubusercontent.com/${this.login}/${this.gist_id}/raw/${this.commit}/${this.filename}`; + }, + size() { + return this.content.length; + }, + truncated: false +}); + +/* Sample + +"about.template.hbs": { + "filename": "about.template.hbs", + "type": "text/plain", + "language": "Handlebars", + "raw_url": "https://gist.githubusercontent.com/Gaurav0/35de43cb81fc35ddffb2/raw/b7332edd46bd97973c1dfebf495908b8abb9b301/about.template.hbs", + "size": 17, + "truncated": false, + "content": "
About Page
" +}, + */ diff --git a/app/mirage/factories/gist.js b/app/mirage/factories/gist.js new file mode 100644 index 00000000..808c435b --- /dev/null +++ b/app/mirage/factories/gist.js @@ -0,0 +1,218 @@ +/** + * This is a factory definition for a gist. + */ +import Mirage/*, {faker} */ from 'ember-cli-mirage'; + +export default Mirage.Factory.extend({ + url() { + return "https://api.github.com/gists/" + this.id; + }, + forks_url() { + return `https://api.github.com/gists/${this.id}/forks`; + }, + commits_url() { + return `https://api.github.com/gists/${this.id}/commits`; + }, + git_pull_url() { + return `https://gist.github.com/${this.id}.git`; + }, + git_push_url() { + return `https://gist.github.com/${this.id}.git`; + }, + html_url() { + return "https://gist.github.com/" + this.id; + }, + //files, + public: true, + created_at: "2015-07-23T22:30:30Z", + updated_at: "2015-07-23T22:49:45Z", + description: "New Twiddle", + comments: 0, + user: null, + comments_url() { + return `https://api.github.com/gists/${this.id}/comments`; + }, + //owner, + forks: [], + history: [] +}); + +/* Sample +{ + "url": "https://api.github.com/gists/35de43cb81fc35ddffb2", + "forks_url": "https://api.github.com/gists/35de43cb81fc35ddffb2/forks", + "commits_url": "https://api.github.com/gists/35de43cb81fc35ddffb2/commits", + "id": "35de43cb81fc35ddffb2", + "git_pull_url": "https://gist.github.com/35de43cb81fc35ddffb2.git", + "git_push_url": "https://gist.github.com/35de43cb81fc35ddffb2.git", + "html_url": "https://gist.github.com/35de43cb81fc35ddffb2", + "files": { + "about.template.hbs": { + "filename": "about.template.hbs", + "type": "text/plain", + "language": "Handlebars", + "raw_url": "https://gist.githubusercontent.com/Gaurav0/35de43cb81fc35ddffb2/raw/b7332edd46bd97973c1dfebf495908b8abb9b301/about.template.hbs", + "size": 17, + "truncated": false, + "content": "About Page
" + }, + "application.template.hbs": { + "filename": "application.template.hbs", + "type": "text/plain", + "language": "Handlebars", + "raw_url": "https://gist.githubusercontent.com/Gaurav0/35de43cb81fc35ddffb2/raw/f354c6698b02fe3243656c8dc5aa0303cc7ae81c/application.template.hbs", + "size": 87, + "truncated": false, + "content": "{{#link-to \"index\"}}Index{{/link-to}}\n{{#link-to \"about\"}}About{{/link-to}}\n\n{{outlet}}" + }, + "index.template.hbs": { + "filename": "index.template.hbs", + "type": "text/plain", + "language": "Handlebars", + "raw_url": "https://gist.githubusercontent.com/Gaurav0/35de43cb81fc35ddffb2/raw/60a449a6591c3bd2ba7389354146c264b13c3166/index.template.hbs", + "size": 16, + "truncated": false, + "content": "Main Page
" + }, + "router.js": { + "filename": "router.js", + "type": "application/javascript", + "language": "JavaScript", + "raw_url": "https://gist.githubusercontent.com/Gaurav0/35de43cb81fc35ddffb2/raw/0ef881458f8154407d50509be3598b31392d8153/router.js", + "size": 218, + "truncated": false, + "content": "import Ember from 'ember';\nimport config from './config/environment';\n\nvar Router = Ember.Router.extend({\n location: config.locationType\n});\n\nRouter.map(function() {\n this.route(\"about\");\n});\n\nexport default Router;\n" + }, + "twiddle.json": { + "filename": "twiddle.json", + "type": "application/json", + "language": "JSON", + "raw_url": "https://gist.githubusercontent.com/Gaurav0/35de43cb81fc35ddffb2/raw/8b44c317f1c80721a3a74f542ca0c55a01a5badf/twiddle.json", + "size": 303, + "truncated": false, + "content": "{\n \"version\": \"0.4.0\",\n \"dependencies\": {\n \"jquery\": \"https://cdnjs.cloudflare.com/ajax/libs/jquery/1.11.3/jquery.js\",\n \"ember\": \"https://cdnjs.cloudflare.com/ajax/libs/ember.js/1.13.5/ember.js\",\n \"ember-data\": \"https://cdnjs.cloudflare.com/ajax/libs/ember-data.js/1.13.5/ember-data.js\"\n }\n}" + } +}, + "public": true, + "created_at": "2015-07-23T22:30:30Z", + "updated_at": "2015-07-23T22:49:45Z", + "description": "New Twiddle", + "comments": 0, + "user": null, + "comments_url": "https://api.github.com/gists/35de43cb81fc35ddffb2/comments", + "owner": { + "login": "Gaurav0", + "id": 313960, + "avatar_url": "https://avatars.githubusercontent.com/u/313960?v=3", + "gravatar_id": "", + "url": "https://api.github.com/users/Gaurav0", + "html_url": "https://github.com/Gaurav0", + "followers_url": "https://api.github.com/users/Gaurav0/followers", + "following_url": "https://api.github.com/users/Gaurav0/following{/other_user}", + "gists_url": "https://api.github.com/users/Gaurav0/gists{/gist_id}", + "starred_url": "https://api.github.com/users/Gaurav0/starred{/owner}{/repo}", + "subscriptions_url": "https://api.github.com/users/Gaurav0/subscriptions", + "organizations_url": "https://api.github.com/users/Gaurav0/orgs", + "repos_url": "https://api.github.com/users/Gaurav0/repos", + "events_url": "https://api.github.com/users/Gaurav0/events{/privacy}", + "received_events_url": "https://api.github.com/users/Gaurav0/received_events", + "type": "User", + "site_admin": false +}, + "forks": [ + +], + "history": [ + { + "user": { + "login": "Gaurav0", + "id": 313960, + "avatar_url": "https://avatars.githubusercontent.com/u/313960?v=3", + "gravatar_id": "", + "url": "https://api.github.com/users/Gaurav0", + "html_url": "https://github.com/Gaurav0", + "followers_url": "https://api.github.com/users/Gaurav0/followers", + "following_url": "https://api.github.com/users/Gaurav0/following{/other_user}", + "gists_url": "https://api.github.com/users/Gaurav0/gists{/gist_id}", + "starred_url": "https://api.github.com/users/Gaurav0/starred{/owner}{/repo}", + "subscriptions_url": "https://api.github.com/users/Gaurav0/subscriptions", + "organizations_url": "https://api.github.com/users/Gaurav0/orgs", + "repos_url": "https://api.github.com/users/Gaurav0/repos", + "events_url": "https://api.github.com/users/Gaurav0/events{/privacy}", + "received_events_url": "https://api.github.com/users/Gaurav0/received_events", + "type": "User", + "site_admin": false + }, + "version": "921e8958fe32b5a1b724fa6754d0dd904cfa9e62", + "committed_at": "2015-07-23T22:49:45Z", + "change_status": { + "total": 1, + "additions": 1, + "deletions": 0 + }, + "url": "https://api.github.com/gists/35de43cb81fc35ddffb2/921e8958fe32b5a1b724fa6754d0dd904cfa9e62" + }, + { + "user": { + "login": "Gaurav0", + "id": 313960, + "avatar_url": "https://avatars.githubusercontent.com/u/313960?v=3", + "gravatar_id": "", + "url": "https://api.github.com/users/Gaurav0", + "html_url": "https://github.com/Gaurav0", + "followers_url": "https://api.github.com/users/Gaurav0/followers", + "following_url": "https://api.github.com/users/Gaurav0/following{/other_user}", + "gists_url": "https://api.github.com/users/Gaurav0/gists{/gist_id}", + "starred_url": "https://api.github.com/users/Gaurav0/starred{/owner}{/repo}", + "subscriptions_url": "https://api.github.com/users/Gaurav0/subscriptions", + "organizations_url": "https://api.github.com/users/Gaurav0/orgs", + "repos_url": "https://api.github.com/users/Gaurav0/repos", + "events_url": "https://api.github.com/users/Gaurav0/events{/privacy}", + "received_events_url": "https://api.github.com/users/Gaurav0/received_events", + "type": "User", + "site_admin": false + }, + "version": "e0c766099ae77ceaa4fafc0a61f536b469fe4840", + "committed_at": "2015-07-23T22:48:50Z", + "change_status": { + "total": 1, + "additions": 1, + "deletions": 0 + }, + "url": "https://api.github.com/gists/35de43cb81fc35ddffb2/e0c766099ae77ceaa4fafc0a61f536b469fe4840" + }, + { + "user": { + "login": "Gaurav0", + "id": 313960, + "avatar_url": "https://avatars.githubusercontent.com/u/313960?v=3", + "gravatar_id": "", + "url": "https://api.github.com/users/Gaurav0", + "html_url": "https://github.com/Gaurav0", + "followers_url": "https://api.github.com/users/Gaurav0/followers", + "following_url": "https://api.github.com/users/Gaurav0/following{/other_user}", + "gists_url": "https://api.github.com/users/Gaurav0/gists{/gist_id}", + "starred_url": "https://api.github.com/users/Gaurav0/starred{/owner}{/repo}", + "subscriptions_url": "https://api.github.com/users/Gaurav0/subscriptions", + "organizations_url": "https://api.github.com/users/Gaurav0/orgs", + "repos_url": "https://api.github.com/users/Gaurav0/repos", + "events_url": "https://api.github.com/users/Gaurav0/events{/privacy}", + "received_events_url": "https://api.github.com/users/Gaurav0/received_events", + "type": "User", + "site_admin": false + }, + "version": "b42740fa0ee5b3af9ef29c005b10906932dad930", + "committed_at": "2015-07-23T22:30:30Z", + "change_status": { + "total": 24, + "additions": 24, + "deletions": 0 + }, + "url": "https://api.github.com/gists/35de43cb81fc35ddffb2/b42740fa0ee5b3af9ef29c005b10906932dad930" + } +] +} +*/ + + + diff --git a/app/mirage/factories/owner.js b/app/mirage/factories/owner.js new file mode 100644 index 00000000..63cdd5a7 --- /dev/null +++ b/app/mirage/factories/owner.js @@ -0,0 +1,69 @@ +/** + * This is a factory definition for an owner + */ +import Mirage, { faker } from 'ember-cli-mirage'; + +export default Mirage.Factory.extend({ + id: faker.random.number(99999), + avatar_url() { + return `https://avatars.githubusercontent.com/u/${this.id}?v=3`; + }, + gravatar_id: "", + url() { + return "https://api.github.com/users/" + this.login; + }, + html_url() { + return "https://github.com/" + this.login; + }, + followers_url() { + return `https://api.github.com/users/${this.login}/followers`; + }, + following_url() { + return `https://api.github.com/users/${this.login}/following{/other_user}`; + }, + gists_url() { + return `https://api.github.com/users/${this.login}/gists{/gist_id}`; + }, + starred_url() { + return `https://api.github.com/users/${this.login}/starred{/owner}{/repo}`; + }, + subscriptions_url() { + return `https://api.github.com/users/${this.login}/subscriptions`; + }, + organizations_url() { + return `https://api.github.com/users/${this.login}/orgs`; + }, + repos_url() { + return `https://api.github.com/users/${this.login}/repos`; + }, + events_url() { + return `https://api.github.com/users/${this.login}/events{/privacy}`; + }, + received_events_url() { + return `https://api.github.com/users/${this.login}/received_events`; + }, + type: "User", + site_admin: false +}); + +/* Sample + "owner": { + "login": "Gaurav0", + "id": 313960, + "avatar_url": "https://avatars.githubusercontent.com/u/313960?v=3", + "gravatar_id": "", + "url": "https://api.github.com/users/Gaurav0", + "html_url": "https://github.com/Gaurav0", + "followers_url": "https://api.github.com/users/Gaurav0/followers", + "following_url": "https://api.github.com/users/Gaurav0/following{/other_user}", + "gists_url": "https://api.github.com/users/Gaurav0/gists{/gist_id}", + "starred_url": "https://api.github.com/users/Gaurav0/starred{/owner}{/repo}", + "subscriptions_url": "https://api.github.com/users/Gaurav0/subscriptions", + "organizations_url": "https://api.github.com/users/Gaurav0/orgs", + "repos_url": "https://api.github.com/users/Gaurav0/repos", + "events_url": "https://api.github.com/users/Gaurav0/events{/privacy}", + "received_events_url": "https://api.github.com/users/Gaurav0/received_events", + "type": "User", + "site_admin": false + }, + */ diff --git a/app/mirage/scenarios/default.js b/app/mirage/scenarios/default.js new file mode 100644 index 00000000..e07271cc --- /dev/null +++ b/app/mirage/scenarios/default.js @@ -0,0 +1,7 @@ +export default function(/* server */) { + + // Seed your development database using your factories. This + // data will not be loaded in your tests. + + // server.createList('contact', 10); +} diff --git a/bower.json b/bower.json index 720b68ad..d2878cd8 100644 --- a/bower.json +++ b/bower.json @@ -15,7 +15,11 @@ "codemirror": "~5.4.0", "ember-cli-codemirror-shim": "~0.0.1", "bootstrap-sass-official": "~3.3.4", - "dom-ruler": "0.1.5" + "dom-ruler": "0.1.5", + "pretender": "~0.6.0", + "ember-inflector": "~1.3.1", + "lodash": "~3.7.0", + "Faker": "~2.1.3" }, "resolutions": { "codemirror": "~5.4.0" diff --git a/config/environment.js b/config/environment.js index 84f148ec..8783e5a1 100644 --- a/config/environment.js +++ b/config/environment.js @@ -6,8 +6,9 @@ module.exports = function(environment) { environment: environment, baseURL: '/', locationType: 'auto', + host: 'https://api.github.com', githubOauthUrl: 'http://localhost:9999/authenticate/', - assetsHost: environment==='production' ? '//assets.ember-twiddle.com/' : '', + assetsHost: environment==='production' ? '//assets.ember-twiddle.com/' : '/', EmberENV: { FEATURES: { // Here you can enable experimental features on an ember canary build @@ -39,6 +40,10 @@ module.exports = function(environment) { // ENV.APP.LOG_TRANSITIONS = true; // ENV.APP.LOG_TRANSITIONS_INTERNAL = true; // ENV.APP.LOG_VIEW_LOOKUPS = true; + + ENV['ember-cli-mirage'] = { + enabled: false + } } if (environment === 'test') { @@ -51,6 +56,8 @@ module.exports = function(environment) { ENV.APP.LOG_VIEW_LOOKUPS = false; ENV.APP.rootElement = '#ember-testing'; + + ENV.host = undefined; } if (environment === 'production') { diff --git a/package.json b/package.json index 49a4ed8a..9609083b 100644 --- a/package.json +++ b/package.json @@ -42,6 +42,7 @@ "ember-cli-htmlbars-inline-precompile": "^0.1.1", "ember-cli-ic-ajax": "0.2.1", "ember-cli-inject-live-reload": "^1.3.0", + "ember-cli-mirage": "0.1.5", "ember-cli-qunit": "0.3.15", "ember-cli-release": "^0.2.5", "ember-cli-uglify": "^1.0.1", diff --git a/tests/.jshintrc b/tests/.jshintrc index 6ec0b7c1..4f9f51d8 100644 --- a/tests/.jshintrc +++ b/tests/.jshintrc @@ -1,5 +1,6 @@ { "predef": [ + "server", "document", "window", "location", diff --git a/tests/acceptance/routing-test.js b/tests/acceptance/routing-test.js new file mode 100644 index 00000000..3237ef39 --- /dev/null +++ b/tests/acceptance/routing-test.js @@ -0,0 +1,101 @@ +import Ember from 'ember'; +import { module, test } from 'qunit'; +import startApp from 'ember-twiddle/tests/helpers/start-app'; + +let application; + +module('Acceptance | routing', { + beforeEach: function() { + application = startApp(); + }, + + afterEach: function() { + Ember.run(application, 'destroy'); + } +}); + +test('Able to do routing in a gist', function(assert) { + const login = "Gaurav0"; + const gist_id = "35de43cb81fc35ddffb2"; + const commit = "f354c6698b02fe3243656c8dc5aa0303cc7ae81c"; + + function create_file(filename, content) { + return server.create('gist-file', { + filename: filename, + login: login, + gist_id: gist_id, + commit: commit, + content: content + }); + } + + const aboutTemplate = create_file("about.template.hbs", "About Page
"); + const indexTemplate = create_file("index.template.hbs", "Main Page
"); + + const appTemplate = create_file("application.template.hbs", + "{{#link-to \"index\" class=\"test-index-link\"}}Index{{/link-to}}\n{{#link-to \"about\" class=\"test-about-link\"}}About{{/link-to}}\n\n{{outlet}}"); + + const router = create_file("router.js", + "import Ember from 'ember';\nimport config from './config/environment';\n\nvar Router = Ember.Router.extend({\n location: config.locationType\n});\n\nRouter.map(function() {\n this.route(\"about\");\n});\n\nexport default Router;\n"); + + const twiddleJson = create_file("twiddle.json", + "{\n \"version\": \"0.4.0\",\n \"dependencies\": {\n \"jquery\": \"https://cdnjs.cloudflare.com/ajax/libs/jquery/1.11.3/jquery.js\",\n \"ember\": \"https://cdnjs.cloudflare.com/ajax/libs/ember.js/1.13.5/ember.js\",\n \"ember-data\": \"https://cdnjs.cloudflare.com/ajax/libs/ember-data.js/1.13.5/ember-data.js\"\n }\n}"); + + const setupTest = create_file("initializers.setup-test.js", + "import Ember from 'ember';\n\nexport default {\n name: 'setup-test',\n initialize: function(container, app) {\n app.setupForTesting();\n app.injectTestHelpers();\n window.QUnit = window.parent.QUnit;\n }\n};"); + + let files = {}; + [ + appTemplate, + aboutTemplate, + indexTemplate, + router, + twiddleJson, + setupTest + ].forEach(function(file) { + files[file.filename] = file; + }); + + const owner = server.create('owner', {login: login}); + server.create('gist', { + id: gist_id, + owner: owner, + files: files + }); + + const iframe = '#dummy-content-iframe'; + const aboutLink = '.ember-application .test-about-link'; + const indexLink = '.ember-application .test-index-link'; + const outletText = '.ember-application p'; + let iframe_window; + + visit('/35de43cb81fc35ddffb2'); + + andThen(function() { + iframe_window = find(iframe)[0].contentWindow; + + // Wait until iframe loads + return new Ember.RSVP.Promise(function (resolve) { + iframe_window.addEventListener('load', function () { + iframe_window.removeEventListener('load'); + return resolve(); + }); + }); + }); + + andThen(function() { + iframe_window.visit('/'); + }); + + andThen(function() { + iframe_window.click(find(iframe).contents().find(aboutLink)); + }); + andThen(function() { + assert.equal(find(iframe).contents().find(outletText).text().trim(), 'About Page', 'About Link leads to About Page being displayed'); + + iframe_window.click(find(iframe).contents().find(indexLink)); + }); + andThen(function() { + assert.equal(find(iframe).contents().find(outletText).text().trim(), 'Main Page', 'Index Link leads to Main Page being displayed'); + }); +});