From 0471ad393c6e61630bf044802d85a1583711e79d Mon Sep 17 00:00:00 2001 From: Robin Ward Date: Wed, 24 Aug 2016 14:35:07 -0400 Subject: [PATCH] Scaffold for new Wizard - Rails / Ember / Tests --- app/assets/javascripts/discourse-objects.js | 2 + app/assets/javascripts/env.js | 5 --- app/assets/javascripts/vendor.js | 1 + app/assets/javascripts/wizard-application.js | 6 +++ app/assets/javascripts/wizard-vendor.js | 2 + .../wizard/controllers/step.js.es6 | 3 ++ app/assets/javascripts/wizard/resolver.js.es6 | 26 ++++++++++++ app/assets/javascripts/wizard/router.js.es6 | 7 +++ .../javascripts/wizard/routes/index.js.es6 | 5 +++ .../javascripts/wizard/routes/step.js.es6 | 12 ++++++ .../wizard/templates/application.hbs | 7 +++ .../javascripts/wizard/templates/step.hbs | 3 ++ .../wizard/test/acceptance/wizard-test.js.es6 | 10 +++++ .../javascripts/wizard/test/test_helper.js | 40 ++++++++++++++++++ app/assets/javascripts/wizard/wizard.js.es6 | 8 ++++ app/assets/stylesheets/wizard.scss | 31 ++++++++++++++ app/controllers/wizard/wizard_controller.rb | 16 +++++++ app/views/wizard/wizard/index.html.erb | 21 +++++++++ app/views/wizard/wizard/qunit.html.erb | 15 +++++++ config/application.rb | 3 +- config/routes.rb | 5 +++ public/images/wizard/bubbles.png | Bin 0 -> 29250 bytes .../wizard/wizard_controller_spec.rb | 25 +++++++++++ 23 files changed, 247 insertions(+), 6 deletions(-) create mode 100644 app/assets/javascripts/discourse-objects.js create mode 100644 app/assets/javascripts/wizard-application.js create mode 100644 app/assets/javascripts/wizard-vendor.js create mode 100644 app/assets/javascripts/wizard/controllers/step.js.es6 create mode 100644 app/assets/javascripts/wizard/resolver.js.es6 create mode 100644 app/assets/javascripts/wizard/router.js.es6 create mode 100644 app/assets/javascripts/wizard/routes/index.js.es6 create mode 100644 app/assets/javascripts/wizard/routes/step.js.es6 create mode 100644 app/assets/javascripts/wizard/templates/application.hbs create mode 100644 app/assets/javascripts/wizard/templates/step.hbs create mode 100644 app/assets/javascripts/wizard/test/acceptance/wizard-test.js.es6 create mode 100644 app/assets/javascripts/wizard/test/test_helper.js create mode 100644 app/assets/javascripts/wizard/wizard.js.es6 create mode 100644 app/assets/stylesheets/wizard.scss create mode 100644 app/controllers/wizard/wizard_controller.rb create mode 100644 app/views/wizard/wizard/index.html.erb create mode 100644 app/views/wizard/wizard/qunit.html.erb create mode 100644 public/images/wizard/bubbles.png create mode 100644 spec/controllers/wizard/wizard_controller_spec.rb diff --git a/app/assets/javascripts/discourse-objects.js b/app/assets/javascripts/discourse-objects.js new file mode 100644 index 000000000..d55626ef0 --- /dev/null +++ b/app/assets/javascripts/discourse-objects.js @@ -0,0 +1,2 @@ +window.Discourse = {}; +Discourse.SiteSettings = {}; diff --git a/app/assets/javascripts/env.js b/app/assets/javascripts/env.js index 5537a6c10..d5fe88236 100644 --- a/app/assets/javascripts/env.js +++ b/app/assets/javascripts/env.js @@ -1,8 +1,3 @@ window.ENV = { }; - -window.Discourse = {}; -Discourse.SiteSettings = {}; - window.EmberENV = window.EmberENV || {}; window.EmberENV['FORCE_JQUERY'] = true; - diff --git a/app/assets/javascripts/vendor.js b/app/assets/javascripts/vendor.js index a6a8c8142..22624ed00 100644 --- a/app/assets/javascripts/vendor.js +++ b/app/assets/javascripts/vendor.js @@ -1,5 +1,6 @@ //= require logster //= require ./env +//= require ./discourse-objects //= require probes.js //= require template_include.js diff --git a/app/assets/javascripts/wizard-application.js b/app/assets/javascripts/wizard-application.js new file mode 100644 index 000000000..1d77f9dfa --- /dev/null +++ b/app/assets/javascripts/wizard-application.js @@ -0,0 +1,6 @@ +//= require wizard/resolver +//= require wizard/router +//= require wizard/wizard +//= require_tree ./wizard/templates +//= require_tree ./wizard/routes +//= require_tree ./wizard/controllers diff --git a/app/assets/javascripts/wizard-vendor.js b/app/assets/javascripts/wizard-vendor.js new file mode 100644 index 000000000..cb0647466 --- /dev/null +++ b/app/assets/javascripts/wizard-vendor.js @@ -0,0 +1,2 @@ +//= require env +//= require template_include.js diff --git a/app/assets/javascripts/wizard/controllers/step.js.es6 b/app/assets/javascripts/wizard/controllers/step.js.es6 new file mode 100644 index 000000000..bc7c7b20b --- /dev/null +++ b/app/assets/javascripts/wizard/controllers/step.js.es6 @@ -0,0 +1,3 @@ +export default Ember.Controller.extend({ + step: null, +}); diff --git a/app/assets/javascripts/wizard/resolver.js.es6 b/app/assets/javascripts/wizard/resolver.js.es6 new file mode 100644 index 000000000..c89bfa593 --- /dev/null +++ b/app/assets/javascripts/wizard/resolver.js.es6 @@ -0,0 +1,26 @@ +function resolveType(parsedName) { + const entries = requirejs.entries; + + const named = `wizard/${parsedName.type}s/${parsedName.fullNameWithoutType}`; + if (entries[named]) { + const module = require(named, null, null, true /* force sync */); + return module.default; + } +} + +export default Ember.DefaultResolver.extend({ + + resolveRoute(parsedName) { + return resolveType(parsedName) || this._super(parsedName); + }, + + resolveController(parsedName) { + return resolveType(parsedName) || this._super(parsedName); + }, + + resolveTemplate(parsedName) { + const templates = Ember.TEMPLATES; + const withoutType = parsedName.fullNameWithoutType; + return templates[`wizard/templates/${withoutType}`] || this._super(parsedName); + } +}); diff --git a/app/assets/javascripts/wizard/router.js.es6 b/app/assets/javascripts/wizard/router.js.es6 new file mode 100644 index 000000000..d110766f8 --- /dev/null +++ b/app/assets/javascripts/wizard/router.js.es6 @@ -0,0 +1,7 @@ +const Router = Ember.Router.extend(); + +Router.map(function () { + this.route('step', { path: '/step/:step_id' }); +}); + +export default Router; diff --git a/app/assets/javascripts/wizard/routes/index.js.es6 b/app/assets/javascripts/wizard/routes/index.js.es6 new file mode 100644 index 000000000..2587b35d8 --- /dev/null +++ b/app/assets/javascripts/wizard/routes/index.js.es6 @@ -0,0 +1,5 @@ +export default Ember.Route.extend({ + beforeModel() { + this.replaceWith('step', 'welcome'); + } +}); diff --git a/app/assets/javascripts/wizard/routes/step.js.es6 b/app/assets/javascripts/wizard/routes/step.js.es6 new file mode 100644 index 000000000..4de6d180e --- /dev/null +++ b/app/assets/javascripts/wizard/routes/step.js.es6 @@ -0,0 +1,12 @@ +export default Ember.Route.extend({ + model(params) { + return { + id: params.step_id, + title: "You're a wizard harry!" + }; + }, + + setupController(controller, model) { + controller.set('step', model); + } +}); diff --git a/app/assets/javascripts/wizard/templates/application.hbs b/app/assets/javascripts/wizard/templates/application.hbs new file mode 100644 index 000000000..52416fc45 --- /dev/null +++ b/app/assets/javascripts/wizard/templates/application.hbs @@ -0,0 +1,7 @@ +
+
+ Discourse! + + {{outlet}} +
+
diff --git a/app/assets/javascripts/wizard/templates/step.hbs b/app/assets/javascripts/wizard/templates/step.hbs new file mode 100644 index 000000000..c8e09a81f --- /dev/null +++ b/app/assets/javascripts/wizard/templates/step.hbs @@ -0,0 +1,3 @@ +
+ {{step.title}} +
diff --git a/app/assets/javascripts/wizard/test/acceptance/wizard-test.js.es6 b/app/assets/javascripts/wizard/test/acceptance/wizard-test.js.es6 new file mode 100644 index 000000000..f166e7b24 --- /dev/null +++ b/app/assets/javascripts/wizard/test/acceptance/wizard-test.js.es6 @@ -0,0 +1,10 @@ + +module("Acceptance: wizard"); + +test("Wizard loads", assert => { + visit("/"); + andThen(() => { + assert.ok(exists('.wizard-column-contents')); + assert.equal(currentPath(), 'steps'); + }); +}); diff --git a/app/assets/javascripts/wizard/test/test_helper.js b/app/assets/javascripts/wizard/test/test_helper.js new file mode 100644 index 000000000..529c5e9b8 --- /dev/null +++ b/app/assets/javascripts/wizard/test/test_helper.js @@ -0,0 +1,40 @@ +/*global document, sinon, QUnit, Logster */ + +//= require env +//= require jquery.debug +//= require loader +//= require jquery.debug +//= require handlebars +//= require ember.debug +//= require ember-template-compiler +//= require ember-qunit +//= require wizard-application +//= require helpers/assertions +//= require_tree ./acceptance + +// Trick JSHint into allow document.write +var d = document; +d.write('
'); +d.write(''); + +if (window.Logster) { + Logster.enabled = false; +} else { + window.Logster = { enabled: false }; +} + +var wizard = require('wizard/wizard').default.create({ + rootElement: '#ember-testing' +}); +wizard.setupForTesting(); +wizard.injectTestHelpers(); + +QUnit.testDone(function() { + wizard.reset(); +}); + +Object.keys(requirejs.entries).forEach(function(entry) { + if ((/\-test/).test(entry)) { + require(entry, null, null, true); + } +}); diff --git a/app/assets/javascripts/wizard/wizard.js.es6 b/app/assets/javascripts/wizard/wizard.js.es6 new file mode 100644 index 000000000..6318fec2b --- /dev/null +++ b/app/assets/javascripts/wizard/wizard.js.es6 @@ -0,0 +1,8 @@ +import Resolver from 'wizard/resolver'; +import Router from 'wizard/router'; + +export default Ember.Application.extend({ + rootElement: '#wizard-main', + Resolver, + Router +}); diff --git a/app/assets/stylesheets/wizard.scss b/app/assets/stylesheets/wizard.scss new file mode 100644 index 000000000..228b399f5 --- /dev/null +++ b/app/assets/stylesheets/wizard.scss @@ -0,0 +1,31 @@ +@import "vendor/normalize"; +@import "vendor/font_awesome/font-awesome"; + +body { + background-color: rgb(231,238,247); + background-image: url('/images/wizard/bubbles.png'); + background-repeat: repeat; + background-position: left top; +} + +.wizard-column { + background-color: white; + border-radius: 2px; + box-shadow: 0 5px 10px rgba(0,0,0,0.2); + box-sizing: border-box; + margin: 0.75rem auto; + padding: 0; + max-width: 700px; + min-width: 280px; + width: 100%; + border: 1px solid #ccc; + + .wizard-column-contents { + padding: 1em; + + h1 { + margin: 0; + } + } +} + diff --git a/app/controllers/wizard/wizard_controller.rb b/app/controllers/wizard/wizard_controller.rb new file mode 100644 index 000000000..09e7ae1f9 --- /dev/null +++ b/app/controllers/wizard/wizard_controller.rb @@ -0,0 +1,16 @@ +class Wizard::WizardController < ApplicationController + + before_filter :ensure_logged_in + before_filter :ensure_staff + + skip_before_filter :check_xhr, :preload_json + + layout false + + def index + end + + def qunit + end + +end diff --git a/app/views/wizard/wizard/index.html.erb b/app/views/wizard/wizard/index.html.erb new file mode 100644 index 000000000..249921a4e --- /dev/null +++ b/app/views/wizard/wizard/index.html.erb @@ -0,0 +1,21 @@ + + + <%= stylesheet_link_tag 'wizard' %> + <%= javascript_include_tag 'wizard-vendor' %> + <%= javascript_include_tag 'ember_jquery' %> + <%= javascript_include_tag 'wizard-application' %> + + + +
+
+ + + + + + diff --git a/app/views/wizard/wizard/qunit.html.erb b/app/views/wizard/wizard/qunit.html.erb new file mode 100644 index 000000000..814bfb5c9 --- /dev/null +++ b/app/views/wizard/wizard/qunit.html.erb @@ -0,0 +1,15 @@ + + + + QUnit Test Runner + <%= stylesheet_link_tag "qunit" %> + <%= stylesheet_link_tag "test_helper" %> + <%= javascript_include_tag "qunit" %> + <%= javascript_include_tag "wizard/test/test_helper" %> + <%= csrf_meta_tags %> + + +
+
+ + diff --git a/config/application.rb b/config/application.rb index 577d12799..70d4427f7 100644 --- a/config/application.rb +++ b/config/application.rb @@ -72,7 +72,8 @@ module Discourse config.assets.precompile += ['vendor.js', 'common.css', 'desktop.css', 'mobile.css', 'admin.js', 'admin.css', 'shiny/shiny.css', 'preload-store.js.es6', 'browser-update.js', 'embed.css', 'break_string.js', 'ember_jquery.js', - 'pretty-text-bundle.js'] + 'pretty-text-bundle.js', 'wizard.css', 'wizard-application.js', + 'wizard-vendor.js'] # Precompile all available locales Dir.glob("#{config.root}/app/assets/javascripts/locales/*.js.erb").each do |file| diff --git a/config/routes.rb b/config/routes.rb index 131636111..4f516da13 100644 --- a/config/routes.rb +++ b/config/routes.rb @@ -53,6 +53,11 @@ Discourse::Application.routes.draw do resources :forums get "srv/status" => "forums#status" + namespace :wizard, constraints: StaffConstraint.new do + get "" => "wizard#index" + get "qunit" => "wizard#qunit" + end + namespace :admin, constraints: StaffConstraint.new do get "" => "admin#index" diff --git a/public/images/wizard/bubbles.png b/public/images/wizard/bubbles.png new file mode 100644 index 0000000000000000000000000000000000000000..6847ae35926ce6c14a00c2cff6ad73355e506cf7 GIT binary patch literal 29250 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 literal 0 HcmV?d00001 diff --git a/spec/controllers/wizard/wizard_controller_spec.rb b/spec/controllers/wizard/wizard_controller_spec.rb new file mode 100644 index 000000000..d6dcc9a24 --- /dev/null +++ b/spec/controllers/wizard/wizard_controller_spec.rb @@ -0,0 +1,25 @@ +require 'rails_helper' + +describe Wizard::WizardController do + + context 'index' do + render_views + + it 'needs you to be logged in' do + expect { xhr :get, :index }.to raise_error(Discourse::NotLoggedIn) + end + + it "raises an error if you aren't an admin" do + log_in + xhr :get, :index + expect(response).to be_forbidden + end + + it "renders the wizard if you are an admin" do + log_in(:admin) + xhr :get, :index + expect(response).to be_success + end + end + +end