├── app
├── styles
│ └── app.css
├── views
│ └── .gitkeep
├── components
│ └── .gitkeep
├── helpers
│ └── .gitkeep
├── models
│ └── .gitkeep
├── routes
│ └── .gitkeep
├── controllers
│ └── .gitkeep
├── templates
│ └── components
│ │ └── .gitkeep
├── pods
│ ├── login
│ │ ├── template.hbs
│ │ └── route.js
│ ├── track
│ │ ├── template.hbs
│ │ ├── new
│ │ │ ├── template.hbs
│ │ │ └── route.js
│ │ ├── route.js
│ │ └── model.js
│ ├── components
│ │ ├── sx-modal
│ │ │ ├── template.hbs
│ │ │ └── component.js
│ │ ├── login-form
│ │ │ ├── template.hbs
│ │ │ └── component.js
│ │ └── add-track-form
│ │ │ ├── template.hbs
│ │ │ └── component.js
│ ├── application
│ │ ├── adapter.js
│ │ └── template.hbs
│ ├── index
│ │ ├── route.js
│ │ └── template.hbs
│ └── track-list
│ │ ├── controller.js
│ │ ├── model.js
│ │ ├── template.hbs
│ │ └── route.js
├── services
│ └── session.js
├── router.js
├── app.js
├── index.html
└── initializers
│ └── session-service.js
├── vendor
└── .gitkeep
├── tests
├── unit
│ ├── .gitkeep
│ ├── pods
│ │ ├── index
│ │ │ └── route-test.js
│ │ ├── login
│ │ │ └── route-test.js
│ │ ├── track
│ │ │ ├── route-test.js
│ │ │ ├── new
│ │ │ │ └── route-test.js
│ │ │ └── model-test.js
│ │ ├── track-list
│ │ │ ├── route-test.js
│ │ │ ├── model-test.js
│ │ │ └── controller-test.js
│ │ ├── application
│ │ │ └── adapter-test.js
│ │ └── components
│ │ │ ├── sx-modal
│ │ │ └── component-test.js
│ │ │ ├── login-form
│ │ │ └── component-test.js
│ │ │ └── add-track-form
│ │ │ └── component-test.js
│ └── services
│ │ └── session-test.js
├── test-helper.js
├── helpers
│ ├── resolver.js
│ └── start-app.js
├── .jshintrc
└── index.html
├── server
├── .jshintrc
├── index.js
└── mocks
│ ├── track-lists.js
│ └── tracks.js
├── public
├── robots.txt
└── crossdomain.xml
├── .bowerrc
├── testem.json
├── .ember-cli
├── .gitignore
├── .travis.yml
├── bower.json
├── .jshintrc
├── .editorconfig
├── Brocfile.js
├── package.json
├── config
└── environment.js
└── README.md
/app/styles/app.css:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/app/views/.gitkeep:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/vendor/.gitkeep:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/app/components/.gitkeep:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/app/helpers/.gitkeep:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/app/models/.gitkeep:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/app/routes/.gitkeep:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/tests/unit/.gitkeep:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/app/controllers/.gitkeep:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/app/templates/components/.gitkeep:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/server/.jshintrc:
--------------------------------------------------------------------------------
1 | {
2 | "node": true
3 | }
4 |
--------------------------------------------------------------------------------
/public/robots.txt:
--------------------------------------------------------------------------------
1 | # http://www.robotstxt.org
2 | User-agent: *
3 |
--------------------------------------------------------------------------------
/app/pods/login/template.hbs:
--------------------------------------------------------------------------------
1 | {{login-form onLogin="login"}}
2 |
3 | {{outlet}}
4 |
--------------------------------------------------------------------------------
/.bowerrc:
--------------------------------------------------------------------------------
1 | {
2 | "directory": "bower_components",
3 | "analytics": false
4 | }
5 |
--------------------------------------------------------------------------------
/app/pods/track/template.hbs:
--------------------------------------------------------------------------------
1 | {{#with model}}
2 |
{{details}}
3 | {{/with}}
4 |
5 | {{outlet}}
6 |
--------------------------------------------------------------------------------
/app/pods/components/sx-modal/template.hbs:
--------------------------------------------------------------------------------
1 | {{title}}
2 |
3 |
4 |
5 | {{yield}}
6 |
--------------------------------------------------------------------------------
/app/pods/application/adapter.js:
--------------------------------------------------------------------------------
1 | import DS from 'ember-data';
2 |
3 | export default DS.ActiveModelAdapter.extend({
4 | namespace: 'api'
5 | });
6 |
--------------------------------------------------------------------------------
/tests/test-helper.js:
--------------------------------------------------------------------------------
1 | import resolver from './helpers/resolver';
2 | import {
3 | setResolver
4 | } from 'ember-qunit';
5 |
6 | setResolver(resolver);
7 |
--------------------------------------------------------------------------------
/app/pods/index/route.js:
--------------------------------------------------------------------------------
1 | import Ember from 'ember';
2 |
3 | export default Ember.Route.extend({
4 | model () {
5 | return this.store.find('track-list');
6 | }
7 | });
8 |
--------------------------------------------------------------------------------
/app/pods/track-list/controller.js:
--------------------------------------------------------------------------------
1 | import Ember from 'ember';
2 |
3 | export default Ember.Controller.extend({
4 | queryParams: ['page', 'limit'],
5 |
6 | page: 1,
7 | limit: 2
8 | });
9 |
--------------------------------------------------------------------------------
/app/pods/track/new/template.hbs:
--------------------------------------------------------------------------------
1 | Track new
2 |
3 | {{#sx-modal title="Add a new track" onClose="closeModal"}}
4 | {{add-track-form onSave="addTrack"}}
5 | {{/sx-modal}}
6 |
7 | {{outlet}}
8 |
--------------------------------------------------------------------------------
/app/pods/track/route.js:
--------------------------------------------------------------------------------
1 | import Ember from 'ember';
2 |
3 | export default Ember.Route.extend({
4 | model (params) {
5 | return this.store.find('track', params.track_id);
6 | }
7 | });
8 |
--------------------------------------------------------------------------------
/app/services/session.js:
--------------------------------------------------------------------------------
1 | import Ember from 'ember';
2 |
3 | export default Ember.Object.extend({
4 | attemptedTransition: null,
5 | username: null,
6 | isLoggedIn: Ember.computed.notEmpty('username')
7 | });
8 |
--------------------------------------------------------------------------------
/testem.json:
--------------------------------------------------------------------------------
1 | {
2 | "framework": "qunit",
3 | "test_page": "tests/index.html?hidepassed",
4 | "launch_in_ci": [
5 | "PhantomJS"
6 | ],
7 | "launch_in_dev": [
8 | "PhantomJS",
9 | "Chrome"
10 | ]
11 | }
12 |
--------------------------------------------------------------------------------
/app/pods/components/login-form/template.hbs:
--------------------------------------------------------------------------------
1 |
5 |
6 | {{yield}}
7 |
--------------------------------------------------------------------------------
/app/pods/components/sx-modal/component.js:
--------------------------------------------------------------------------------
1 | import Ember from 'ember';
2 |
3 | export default Ember.Component.extend({
4 | title: null,
5 | onClose: null,
6 |
7 | actions: {
8 | closeMe () {
9 | this.sendAction('onClose');
10 | }
11 | }
12 | });
13 |
--------------------------------------------------------------------------------
/app/pods/application/template.hbs:
--------------------------------------------------------------------------------
1 |
2 | {{#link-to 'index'}}
3 | Welcome to Ember.js
4 | {{/link-to}}
5 |
6 |
7 | {{#if session.isLoggedIn}}
8 | {{session.username}}
9 | {{else}}
10 | {{#link-to 'login'}}Login{{/link-to}}
11 | {{/if}}
12 |
13 | {{outlet}}
14 |
--------------------------------------------------------------------------------
/.ember-cli:
--------------------------------------------------------------------------------
1 | {
2 | /**
3 | Ember CLI sends analytics information by default. The data is completely
4 | anonymous, but there are times when you might want to disable this behavior.
5 |
6 | Setting `disableAnalytics` to true will prevent any data from being sent.
7 | */
8 | "disableAnalytics": false
9 | }
10 |
--------------------------------------------------------------------------------
/app/pods/track-list/model.js:
--------------------------------------------------------------------------------
1 | import Ember from 'ember';
2 | import DS from 'ember-data';
3 |
4 | let TrackList = DS.Model.extend({
5 | title: DS.attr('string'),
6 | tracks: DS.hasMany('track'),
7 |
8 | persistentTracks: Ember.computed.filterBy('tracks', 'isNew', false)
9 | });
10 |
11 | export default TrackList;
12 |
--------------------------------------------------------------------------------
/tests/helpers/resolver.js:
--------------------------------------------------------------------------------
1 | import Resolver from 'ember/resolver';
2 | import config from '../../config/environment';
3 |
4 | var resolver = Resolver.create();
5 |
6 | resolver.namespace = {
7 | modulePrefix: config.modulePrefix,
8 | podModulePrefix: config.podModulePrefix
9 | };
10 |
11 | export default resolver;
12 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | # See http://help.github.com/ignore-files/ for more about ignoring files.
2 |
3 | # compiled output
4 | /dist
5 | /tmp
6 |
7 | # dependencies
8 | /node_modules
9 | /bower_components
10 |
11 | # misc
12 | /.sass-cache
13 | /connect.lock
14 | /coverage/*
15 | /libpeerconnection.log
16 | npm-debug.log
17 | testem.log
18 |
--------------------------------------------------------------------------------
/app/pods/index/template.hbs:
--------------------------------------------------------------------------------
1 | Index
2 |
3 |
4 | {{#each model as |trackList| }}
5 | -
6 | {{#link-to 'track-list' trackList.id }}
7 | {{trackList.title}}
8 | {{/link-to}}
9 |
10 | {{else}}
11 | - No tracklists found
12 | {{/each}}
13 |
14 |
15 | {{outlet}}
16 |
--------------------------------------------------------------------------------
/.travis.yml:
--------------------------------------------------------------------------------
1 | ---
2 | language: node_js
3 |
4 | sudo: false
5 |
6 | cache:
7 | directories:
8 | - node_modules
9 |
10 | before_install:
11 | - "npm config set spin false"
12 | - "npm install -g npm@^2"
13 |
14 | install:
15 | - npm install -g bower
16 | - npm install
17 | - bower install
18 |
19 | script:
20 | - npm test
21 |
--------------------------------------------------------------------------------
/tests/unit/pods/index/route-test.js:
--------------------------------------------------------------------------------
1 | import {
2 | moduleFor,
3 | test
4 | } from 'ember-qunit';
5 |
6 | moduleFor('route:index', {
7 | // Specify the other units that are required for this test.
8 | // needs: ['controller:foo']
9 | });
10 |
11 | test('it exists', function(assert) {
12 | var route = this.subject();
13 | assert.ok(route);
14 | });
15 |
--------------------------------------------------------------------------------
/tests/unit/pods/login/route-test.js:
--------------------------------------------------------------------------------
1 | import {
2 | moduleFor,
3 | test
4 | } from 'ember-qunit';
5 |
6 | moduleFor('route:login', {
7 | // Specify the other units that are required for this test.
8 | // needs: ['controller:foo']
9 | });
10 |
11 | test('it exists', function(assert) {
12 | var route = this.subject();
13 | assert.ok(route);
14 | });
15 |
--------------------------------------------------------------------------------
/tests/unit/pods/track/route-test.js:
--------------------------------------------------------------------------------
1 | import {
2 | moduleFor,
3 | test
4 | } from 'ember-qunit';
5 |
6 | moduleFor('route:track', {
7 | // Specify the other units that are required for this test.
8 | // needs: ['controller:foo']
9 | });
10 |
11 | test('it exists', function(assert) {
12 | var route = this.subject();
13 | assert.ok(route);
14 | });
15 |
--------------------------------------------------------------------------------
/tests/unit/pods/track/new/route-test.js:
--------------------------------------------------------------------------------
1 | import {
2 | moduleFor,
3 | test
4 | } from 'ember-qunit';
5 |
6 | moduleFor('route:track/new', {
7 | // Specify the other units that are required for this test.
8 | // needs: ['controller:foo']
9 | });
10 |
11 | test('it exists', function(assert) {
12 | var route = this.subject();
13 | assert.ok(route);
14 | });
15 |
--------------------------------------------------------------------------------
/tests/unit/pods/track-list/route-test.js:
--------------------------------------------------------------------------------
1 | import {
2 | moduleFor,
3 | test
4 | } from 'ember-qunit';
5 |
6 | moduleFor('route:track-list', {
7 | // Specify the other units that are required for this test.
8 | // needs: ['controller:foo']
9 | });
10 |
11 | test('it exists', function(assert) {
12 | var route = this.subject();
13 | assert.ok(route);
14 | });
15 |
--------------------------------------------------------------------------------
/app/pods/track/model.js:
--------------------------------------------------------------------------------
1 | import DS from 'ember-data';
2 |
3 | let Track = DS.Model.extend({
4 | artist: DS.attr('string'),
5 | title: DS.attr('string'),
6 |
7 | trackList: DS.belongsTo('track-list'),
8 |
9 | details: function () {
10 | return this.get('title') + ' by ' + this.get('artist');
11 | }.property('artist', 'title')
12 | });
13 |
14 | export default Track;
15 |
--------------------------------------------------------------------------------
/tests/unit/pods/track/model-test.js:
--------------------------------------------------------------------------------
1 | import {
2 | moduleForModel,
3 | test
4 | } from 'ember-qunit';
5 |
6 | moduleForModel('track', {
7 | // Specify the other units that are required for this test.
8 | needs: []
9 | });
10 |
11 | test('it exists', function(assert) {
12 | var model = this.subject();
13 | // var store = this.store();
14 | assert.ok(!!model);
15 | });
16 |
--------------------------------------------------------------------------------
/tests/unit/pods/track-list/model-test.js:
--------------------------------------------------------------------------------
1 | import {
2 | moduleForModel,
3 | test
4 | } from 'ember-qunit';
5 |
6 | moduleForModel('track-list', {
7 | // Specify the other units that are required for this test.
8 | needs: []
9 | });
10 |
11 | test('it exists', function(assert) {
12 | var model = this.subject();
13 | // var store = this.store();
14 | assert.ok(!!model);
15 | });
16 |
--------------------------------------------------------------------------------
/tests/unit/services/session-test.js:
--------------------------------------------------------------------------------
1 | import {
2 | moduleFor,
3 | test
4 | } from 'ember-qunit';
5 |
6 | moduleFor('service:session', {
7 | // Specify the other units that are required for this test.
8 | // needs: ['service:foo']
9 | });
10 |
11 | // Replace this with your real tests.
12 | test('it exists', function(assert) {
13 | var service = this.subject();
14 | assert.ok(service);
15 | });
16 |
--------------------------------------------------------------------------------
/app/pods/components/add-track-form/template.hbs:
--------------------------------------------------------------------------------
1 |
10 |
11 | {{yield}}
12 |
--------------------------------------------------------------------------------
/tests/unit/pods/track-list/controller-test.js:
--------------------------------------------------------------------------------
1 | import {
2 | moduleFor,
3 | test
4 | } from 'ember-qunit';
5 |
6 | moduleFor('controller:track-list', {
7 | // Specify the other units that are required for this test.
8 | // needs: ['controller:foo']
9 | });
10 |
11 | // Replace this with your real tests.
12 | test('it exists', function(assert) {
13 | var controller = this.subject();
14 | assert.ok(controller);
15 | });
16 |
--------------------------------------------------------------------------------
/app/pods/track-list/template.hbs:
--------------------------------------------------------------------------------
1 | {{model.title}}
2 |
3 |
4 | {{#link-to 'track/new'}}Add a new track{{/link-to}}
5 |
6 |
7 |
8 | {{#each model.persistentTracks as |track| }}
9 | -
10 | {{#link-to 'track' track.id}}
11 | {{track.artist}} - {{track.title}}
12 | {{/link-to}}
13 |
14 | {{else}}
15 | - The list is empty :(
16 | {{/each}}
17 |
18 |
19 | {{outlet}}
20 |
--------------------------------------------------------------------------------
/tests/unit/pods/application/adapter-test.js:
--------------------------------------------------------------------------------
1 | import {
2 | moduleFor,
3 | test
4 | } from 'ember-qunit';
5 |
6 | moduleFor('adapter:application', 'ApplicationAdapter', {
7 | // Specify the other units that are required for this test.
8 | // needs: ['serializer:foo']
9 | });
10 |
11 | // Replace this with your real tests.
12 | test('it exists', function(assert) {
13 | var adapter = this.subject();
14 | assert.ok(adapter);
15 | });
16 |
--------------------------------------------------------------------------------
/app/router.js:
--------------------------------------------------------------------------------
1 | import Ember from 'ember';
2 | import config from './config/environment';
3 |
4 | var Router = Ember.Router.extend({
5 | location: config.locationType
6 | });
7 |
8 | Router.map(function() {
9 | this.resource('track-list', { path: ':track_list_id' }, function () {
10 | this.resource('track/new');
11 | this.resource('track', { path: ':track_id' });
12 | });
13 | this.route('login');
14 | });
15 |
16 | export default Router;
17 |
--------------------------------------------------------------------------------
/app/app.js:
--------------------------------------------------------------------------------
1 | import Ember from 'ember';
2 | import Resolver from 'ember/resolver';
3 | import loadInitializers from 'ember/load-initializers';
4 | import config from './config/environment';
5 |
6 | Ember.MODEL_FACTORY_INJECTIONS = true;
7 |
8 | var App = Ember.Application.extend({
9 | modulePrefix: config.modulePrefix,
10 | podModulePrefix: config.podModulePrefix,
11 | Resolver: Resolver
12 | });
13 |
14 | loadInitializers(App, config.modulePrefix);
15 |
16 | export default App;
17 |
--------------------------------------------------------------------------------
/app/pods/login/route.js:
--------------------------------------------------------------------------------
1 | import Ember from 'ember';
2 |
3 | export default Ember.Route.extend({
4 | actions: {
5 | login: function (username) {
6 | this.session.set('username', username);
7 | let attemptedTransition = this.session.get('attemptedTransition');
8 | if (attemptedTransition) {
9 | this.session.set('attemptedTransition', null);
10 | attemptedTransition.retry();
11 | } else {
12 | this.transitionTo('index');
13 | }
14 | }
15 | }
16 | });
17 |
--------------------------------------------------------------------------------
/app/pods/track/new/route.js:
--------------------------------------------------------------------------------
1 | import Ember from 'ember';
2 |
3 | export default Ember.Route.extend({
4 | actions: {
5 | addTrack: function (form) {
6 | let trackList = this.modelFor('track-list');
7 | form.trackList = trackList;
8 | this.store.createRecord('track', form).save().then(() => {
9 | this.transitionTo('track-list');
10 | });
11 | },
12 |
13 | closeModal: function () {
14 | // TODO: transition to parent route if link was send over
15 | window.history.back();
16 | }
17 | }
18 | });
19 |
--------------------------------------------------------------------------------
/app/pods/components/login-form/component.js:
--------------------------------------------------------------------------------
1 | import Ember from 'ember';
2 |
3 | export default Ember.Component.extend({
4 | username: null,
5 |
6 | prepare: function () {
7 | // is called after this Ember Object is created
8 | }.on('init'),
9 |
10 | setUp: function () {
11 | // `this.element` points to DOM node
12 | // this view occupies.
13 | // Exists only in Components
14 | }.on('didInsertElement'),
15 |
16 | actions: {
17 | login: function () {
18 | this.sendAction('onLogin', this.get('username'));
19 | }
20 | }
21 | });
22 |
--------------------------------------------------------------------------------
/bower.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "sonix",
3 | "dependencies": {
4 | "jquery": "^1.11.1",
5 | "ember": "1.11.0-beta.2",
6 | "ember-data": "1.0.0-beta.15",
7 | "ember-resolver": "~0.1.11",
8 | "loader.js": "ember-cli/loader.js#1.0.1",
9 | "ember-cli-shims": "ember-cli/ember-cli-shims#0.0.3",
10 | "ember-cli-test-loader": "ember-cli-test-loader#0.1.3",
11 | "ember-load-initializers": "ember-cli/ember-load-initializers#0.0.2",
12 | "ember-qunit": "0.2.8",
13 | "ember-qunit-notifications": "0.0.7",
14 | "qunit": "~1.17.1"
15 | }
16 | }
17 |
--------------------------------------------------------------------------------
/tests/unit/pods/components/sx-modal/component-test.js:
--------------------------------------------------------------------------------
1 | import {
2 | moduleForComponent,
3 | test
4 | } from 'ember-qunit';
5 |
6 | moduleForComponent('sx-modal', {
7 | // specify the other units that are required for this test
8 | // needs: ['component:foo', 'helper:bar']
9 | });
10 |
11 | test('it renders', function(assert) {
12 | assert.expect(2);
13 |
14 | // creates the component instance
15 | var component = this.subject();
16 | assert.equal(component._state, 'preRender');
17 |
18 | // renders the component to the page
19 | this.render();
20 | assert.equal(component._state, 'inDOM');
21 | });
22 |
--------------------------------------------------------------------------------
/tests/helpers/start-app.js:
--------------------------------------------------------------------------------
1 | import Ember from 'ember';
2 | import Application from '../../app';
3 | import Router from '../../router';
4 | import config from '../../config/environment';
5 |
6 | export default function startApp(attrs) {
7 | var application;
8 |
9 | var attributes = Ember.merge({}, config.APP);
10 | attributes = Ember.merge(attributes, attrs); // use defaults, but you can override;
11 |
12 | Ember.run(function() {
13 | application = Application.create(attributes);
14 | application.setupForTesting();
15 | application.injectTestHelpers();
16 | });
17 |
18 | return application;
19 | }
20 |
--------------------------------------------------------------------------------
/tests/unit/pods/components/login-form/component-test.js:
--------------------------------------------------------------------------------
1 | import {
2 | moduleForComponent,
3 | test
4 | } from 'ember-qunit';
5 |
6 | moduleForComponent('login-form', {
7 | // specify the other units that are required for this test
8 | // needs: ['component:foo', 'helper:bar']
9 | });
10 |
11 | test('it renders', function(assert) {
12 | assert.expect(2);
13 |
14 | // creates the component instance
15 | var component = this.subject();
16 | assert.equal(component._state, 'preRender');
17 |
18 | // renders the component to the page
19 | this.render();
20 | assert.equal(component._state, 'inDOM');
21 | });
22 |
--------------------------------------------------------------------------------
/.jshintrc:
--------------------------------------------------------------------------------
1 | {
2 | "predef": [
3 | "document",
4 | "window",
5 | "-Promise"
6 | ],
7 | "browser": true,
8 | "boss": true,
9 | "curly": true,
10 | "debug": false,
11 | "devel": true,
12 | "eqeqeq": true,
13 | "evil": true,
14 | "forin": false,
15 | "immed": false,
16 | "laxbreak": false,
17 | "newcap": true,
18 | "noarg": true,
19 | "noempty": false,
20 | "nonew": false,
21 | "nomen": false,
22 | "onevar": false,
23 | "plusplus": false,
24 | "regexp": false,
25 | "undef": true,
26 | "sub": true,
27 | "strict": false,
28 | "white": false,
29 | "eqnull": true,
30 | "esnext": true,
31 | "unused": true
32 | }
33 |
--------------------------------------------------------------------------------
/app/pods/track-list/route.js:
--------------------------------------------------------------------------------
1 | import Ember from 'ember';
2 |
3 | export default Ember.Route.extend({
4 | queryParams: {
5 | page: {
6 | refreshModel: true
7 | },
8 | limit: {
9 | refreshModel: true
10 | },
11 | },
12 |
13 | model (params) {
14 | var tl = null;
15 | return this.store.find('track-list', params.track_list_id).then((trackList) => {
16 | tl = trackList;
17 | let query = {
18 | trackList: trackList.id,
19 | page: params.page,
20 | limit: params.limit
21 | };
22 | return this.store.find('track', query);
23 | }).then(() => tl);
24 | }
25 | });
26 |
--------------------------------------------------------------------------------
/.editorconfig:
--------------------------------------------------------------------------------
1 | # EditorConfig helps developers define and maintain consistent
2 | # coding styles between different editors and IDEs
3 | # editorconfig.org
4 |
5 | root = true
6 |
7 |
8 | [*]
9 | end_of_line = lf
10 | charset = utf-8
11 | trim_trailing_whitespace = true
12 | insert_final_newline = true
13 | indent_style = space
14 | indent_size = 2
15 |
16 | [*.js]
17 | indent_style = space
18 | indent_size = 2
19 |
20 | [*.hbs]
21 | indent_style = space
22 | indent_size = 2
23 |
24 | [*.css]
25 | indent_style = space
26 | indent_size = 2
27 |
28 | [*.html]
29 | indent_style = space
30 | indent_size = 2
31 |
32 | [*.{diff,md}]
33 | trim_trailing_whitespace = false
34 |
--------------------------------------------------------------------------------
/public/crossdomain.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
15 |
16 |
--------------------------------------------------------------------------------
/app/pods/components/add-track-form/component.js:
--------------------------------------------------------------------------------
1 | import Ember from 'ember';
2 |
3 | export default Ember.Component.extend({
4 | title: null,
5 | artist: null,
6 | artistStartsWithUpperCase: true,
7 |
8 | validate () {
9 | let formValues = this.getProperties('title', 'artist');
10 | let artistFirstLetter = formValues.artist[0];
11 | this.set('artistStartsWithUpperCase', artistFirstLetter === artistFirstLetter.toUpperCase());
12 | return this.get('artistStartsWithUpperCase');
13 | },
14 |
15 | actions: {
16 | save: function () {
17 | if (this.validate()) {
18 | this.sendAction('onSave', this.getProperties('title', 'artist'));
19 | }
20 | }
21 | }
22 | });
23 |
--------------------------------------------------------------------------------
/app/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 | Sonix
7 |
8 |
9 |
10 | {{content-for 'head'}}
11 |
12 |
13 |
14 |
15 | {{content-for 'head-footer'}}
16 |
17 |
18 | {{content-for 'body'}}
19 |
20 |
21 |
22 |
23 | {{content-for 'body-footer'}}
24 |
25 |
26 |
--------------------------------------------------------------------------------
/server/index.js:
--------------------------------------------------------------------------------
1 | // To use it create some files under `mocks/`
2 | // e.g. `server/mocks/ember-hamsters.js`
3 | //
4 | // module.exports = function(app) {
5 | // app.get('/ember-hamsters', function(req, res) {
6 | // res.send('hello');
7 | // });
8 | // };
9 |
10 | module.exports = function(app) {
11 | var globSync = require('glob').sync;
12 | var mocks = globSync('./mocks/**/*.js', { cwd: __dirname }).map(require);
13 | var proxies = globSync('./proxies/**/*.js', { cwd: __dirname }).map(require);
14 |
15 | // Log proxy requests
16 | var morgan = require('morgan');
17 | app.use(morgan('dev'));
18 |
19 | mocks.forEach(function(route) { route(app); });
20 | proxies.forEach(function(route) { route(app); });
21 |
22 | };
23 |
--------------------------------------------------------------------------------
/app/initializers/session-service.js:
--------------------------------------------------------------------------------
1 | export function initialize(container, application) {
2 | application.inject('route', 'session', 'service:session');
3 | application.inject('controller:application', 'session', 'service:session');
4 |
5 | application.register('service:session-check', function beforeModel(transition) {
6 | var isLoggedIn = this.session.get('isLoggedIn');
7 | if (!isLoggedIn) {
8 | this.session.set('attemptedTransition', transition);
9 | this.transitionTo('login');
10 | }
11 | }, { instantiate: false });
12 | ['track', 'track/new'].forEach((route) => {
13 | application.inject('route:' + route, 'beforeModel', 'service:session-check');
14 | });
15 | }
16 |
17 | export default {
18 | name: 'session-service',
19 | initialize: initialize
20 | };
21 |
--------------------------------------------------------------------------------
/tests/unit/pods/components/add-track-form/component-test.js:
--------------------------------------------------------------------------------
1 | import {
2 | moduleForComponent,
3 | test
4 | } from 'ember-qunit';
5 |
6 | moduleForComponent('add-track-form', {
7 | // specify the other units that are required for this test
8 | // needs: ['component:foo', 'helper:bar']
9 | });
10 |
11 | test('it renders', function(assert) {
12 | assert.expect(3);
13 |
14 | // creates the component instance
15 | var component = this.subject();
16 | assert.equal(component._state, 'preRender');
17 |
18 | component.set('title', 'test title');
19 | component.set('artist', 'lowercase name');
20 | component.validate();
21 | assert.equal(component.get('artistStartsWithUpperCase'), false);
22 |
23 | // renders the component to the page
24 | this.render();
25 | assert.equal(component._state, 'inDOM');
26 | });
27 |
--------------------------------------------------------------------------------
/Brocfile.js:
--------------------------------------------------------------------------------
1 | /* global require, module */
2 |
3 | var EmberApp = require('ember-cli/lib/broccoli/ember-app');
4 |
5 | var app = new EmberApp({
6 | vendorFiles: {
7 | 'handlebars.js': null
8 | }
9 | });
10 |
11 | // Use `app.import` to add additional libraries to the generated
12 | // output files.
13 | //
14 | // If you need to use different assets in different
15 | // environments, specify an object as the first parameter. That
16 | // object's keys should be the environment name and the values
17 | // should be the asset to use in that environment.
18 | //
19 | // If the library that you are including contains AMD or ES6
20 | // modules that you would like to import into your application
21 | // please specify an object with the list of modules as keys
22 | // along with the exports of each module as its value.
23 |
24 | module.exports = app.toTree();
25 |
--------------------------------------------------------------------------------
/tests/.jshintrc:
--------------------------------------------------------------------------------
1 | {
2 | "predef": [
3 | "document",
4 | "window",
5 | "location",
6 | "setTimeout",
7 | "$",
8 | "-Promise",
9 | "define",
10 | "console",
11 | "visit",
12 | "exists",
13 | "fillIn",
14 | "click",
15 | "keyEvent",
16 | "triggerEvent",
17 | "find",
18 | "findWithAssert",
19 | "wait",
20 | "DS",
21 | "andThen",
22 | "currentURL",
23 | "currentPath",
24 | "currentRouteName"
25 | ],
26 | "node": false,
27 | "browser": false,
28 | "boss": true,
29 | "curly": false,
30 | "debug": false,
31 | "devel": false,
32 | "eqeqeq": true,
33 | "evil": true,
34 | "forin": false,
35 | "immed": false,
36 | "laxbreak": false,
37 | "newcap": true,
38 | "noarg": true,
39 | "noempty": false,
40 | "nonew": false,
41 | "nomen": false,
42 | "onevar": false,
43 | "plusplus": false,
44 | "regexp": false,
45 | "undef": true,
46 | "sub": true,
47 | "strict": false,
48 | "white": false,
49 | "eqnull": true,
50 | "esnext": true
51 | }
52 |
--------------------------------------------------------------------------------
/tests/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 | Sonix Tests
7 |
8 |
9 |
10 | {{content-for 'head'}}
11 | {{content-for 'test-head'}}
12 |
13 |
14 |
15 |
16 |
17 | {{content-for 'head-footer'}}
18 | {{content-for 'test-head-footer'}}
19 |
20 |
21 |
22 | {{content-for 'body'}}
23 | {{content-for 'test-body'}}
24 |
25 |
26 |
27 |
28 |
29 |
30 | {{content-for 'body-footer'}}
31 | {{content-for 'test-body-footer'}}
32 |
33 |
34 |
--------------------------------------------------------------------------------
/server/mocks/track-lists.js:
--------------------------------------------------------------------------------
1 | var FIXTURES = [
2 | { id: '11', title: 'Funky', tracks: [] },
3 | { id: '12', title: 'Lounge', tracks: [] },
4 | { id: '13', title: 'Hasidic Reggae Rock', tracks: [] }
5 | ];
6 |
7 | module.exports = function(app) {
8 | var express = require('express');
9 | var trackListsRouter = express.Router();
10 |
11 | trackListsRouter.get('/', function(req, res) {
12 | res.send({
13 | 'track_lists': FIXTURES
14 | });
15 | });
16 |
17 | trackListsRouter.post('/', function(req, res) {
18 | res.status(201).end();
19 | });
20 |
21 | trackListsRouter.get('/:id', function(req, res) {
22 | res.send({
23 | 'track_lists': FIXTURES.filter(function (trackList) {
24 | return trackList.id == req.params.id;
25 | })[0]
26 | });
27 | });
28 |
29 | trackListsRouter.put('/:id', function(req, res) {
30 | res.send({
31 | 'track_lists': {
32 | id: req.params.id
33 | }
34 | });
35 | });
36 |
37 | trackListsRouter.delete('/:id', function(req, res) {
38 | res.status(204).end();
39 | });
40 |
41 | app.use('/api/track_lists', trackListsRouter);
42 | };
43 |
--------------------------------------------------------------------------------
/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "sonix",
3 | "version": "0.0.0",
4 | "description": "Small description for sonix goes here",
5 | "private": true,
6 | "directories": {
7 | "doc": "doc",
8 | "test": "tests"
9 | },
10 | "scripts": {
11 | "start": "ember server",
12 | "build": "ember build",
13 | "test": "ember test"
14 | },
15 | "repository": "",
16 | "engines": {
17 | "node": ">= 0.10.0"
18 | },
19 | "author": "",
20 | "license": "MIT",
21 | "devDependencies": {
22 | "body-parser": "^1.12.0",
23 | "broccoli-asset-rev": "^2.0.0",
24 | "connect-restreamer": "^1.0.1",
25 | "ember-cli": "0.2.0-beta.1",
26 | "ember-cli-app-version": "0.3.1",
27 | "ember-cli-babel": "^4.0.0",
28 | "ember-cli-content-security-policy": "0.3.0",
29 | "ember-cli-dependency-checker": "0.0.7",
30 | "ember-cli-htmlbars": "0.7.4",
31 | "ember-cli-ic-ajax": "0.1.1",
32 | "ember-cli-inject-live-reload": "^1.3.0",
33 | "ember-cli-qunit": "0.3.8",
34 | "ember-cli-uglify": "1.0.1",
35 | "ember-data": "1.0.0-beta.15",
36 | "ember-export-application-global": "^1.0.2",
37 | "express": "^4.8.5",
38 | "glob": "^4.0.5",
39 | "morgan": "^1.5.1"
40 | }
41 | }
42 |
--------------------------------------------------------------------------------
/config/environment.js:
--------------------------------------------------------------------------------
1 | /* jshint node: true */
2 |
3 | module.exports = function(environment) {
4 | var ENV = {
5 | modulePrefix: 'sonix',
6 | podModulePrefix: 'sonix/pods',
7 | environment: environment,
8 | baseURL: '/',
9 | locationType: 'auto',
10 | EmberENV: {
11 | FEATURES: {
12 | // Here you can enable experimental features on an ember canary build
13 | // e.g. 'with-controller': true
14 | }
15 | },
16 |
17 | APP: {
18 | // Here you can pass flags/options to your application instance
19 | // when it is created
20 | }
21 | };
22 |
23 | if (environment === 'development') {
24 | // ENV.APP.LOG_RESOLVER = true;
25 | // ENV.APP.LOG_ACTIVE_GENERATION = true;
26 | // ENV.APP.LOG_TRANSITIONS = true;
27 | // ENV.APP.LOG_TRANSITIONS_INTERNAL = true;
28 | // ENV.APP.LOG_VIEW_LOOKUPS = true;
29 | }
30 |
31 | if (environment === 'test') {
32 | // Testem prefers this...
33 | ENV.baseURL = '/';
34 | ENV.locationType = 'none';
35 |
36 | // keep test console output quieter
37 | ENV.APP.LOG_ACTIVE_GENERATION = false;
38 | ENV.APP.LOG_VIEW_LOOKUPS = false;
39 |
40 | ENV.APP.rootElement = '#ember-testing';
41 | }
42 |
43 | if (environment === 'production') {
44 |
45 | }
46 |
47 | return ENV;
48 | };
49 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # Sonix
2 |
3 | This README outlines the details of collaborating on this Ember application.
4 | A short introduction of this app could easily go here.
5 |
6 | ## Prerequisites
7 |
8 | You will need the following things properly installed on your computer.
9 |
10 | * [Git](http://git-scm.com/)
11 | * [Node.js](http://nodejs.org/) (with NPM)
12 | * [Bower](http://bower.io/)
13 | * [Ember CLI](http://www.ember-cli.com/)
14 | * [PhantomJS](http://phantomjs.org/)
15 |
16 | ## Installation
17 |
18 | * `git clone ` this repository
19 | * change into the new directory
20 | * `npm install`
21 | * `bower install`
22 |
23 | ## Running / Development
24 |
25 | * `ember server`
26 | * Visit your app at [http://localhost:4200](http://localhost:4200).
27 |
28 | ### Code Generators
29 |
30 | Make use of the many generators for code, try `ember help generate` for more details
31 |
32 | ### Running Tests
33 |
34 | * `ember test`
35 | * `ember test --server`
36 |
37 | ### Building
38 |
39 | * `ember build` (development)
40 | * `ember build --environment production` (production)
41 |
42 | ### Deploying
43 |
44 | Specify what it takes to deploy your app.
45 |
46 | ## Further Reading / Useful Links
47 |
48 | * [ember.js](http://emberjs.com/)
49 | * [ember-cli](http://www.ember-cli.com/)
50 | * Development Browser Extensions
51 | * [ember inspector for chrome](https://chrome.google.com/webstore/detail/ember-inspector/bmdblncegkenkacieihfhpjfppoconhi)
52 | * [ember inspector for firefox](https://addons.mozilla.org/en-US/firefox/addon/ember-inspector/)
53 |
54 |
--------------------------------------------------------------------------------
/server/mocks/tracks.js:
--------------------------------------------------------------------------------
1 | var FIXTURES = [
2 | { id: '21', artist: 'Daft Punk', title: 'Lose Yourself to Dance', trackList: '11' },
3 | { id: '22', artist: 'Chic', title: 'Everybody Dance', trackList: '11' },
4 | { id: '23', artist: 'Chic', title: 'Good Times', trackList: '11' },
5 | { id: '24', artist: 'Tensnake', title: 'Selfish', trackList: '11' },
6 | { id: '25', artist: 'Kool & The Gang', title: 'Tonight', trackList: '11' },
7 | { id: '26', artist: 'Plej', title: 'You', trackList: '12' },
8 | { id: '27', artist: 'Arnold T', title: 'Bang Bang', trackList: '12' },
9 | { id: '28', artist: 'Jerome Isma-Ae', title: 'Underwater Love', trackList: '12' },
10 | { id: '29', artist: 'Matisyahu', title: 'Jerusalem', trackList: '13' }
11 | ];
12 | module.exports = function(app) {
13 | var express = require('express');
14 | var tracksRouter = express.Router();
15 |
16 | tracksRouter.get('/', function(req, res) {
17 | var trackList = req.query.trackList,
18 | page = req.query.page || 1,
19 | limit = req.query.limit || 3;
20 |
21 | var tracks = FIXTURES.filter(function (track) {
22 | if (!trackList) {
23 | return true;
24 | } else {
25 | return track.trackList == trackList;
26 | }
27 | });
28 | res.send({
29 | 'tracks': tracks.filter(function (track, index) {
30 | return index >= (page - 1) * limit && index < page * limit;
31 | }),
32 | meta: {
33 | page: page,
34 | limit: limit,
35 | total: tracks.length
36 | }
37 | });
38 | });
39 |
40 | var next = 10;
41 | tracksRouter.post('/', function(req, res) {
42 | var json = req.body;
43 | json.track.id = '2' + next;
44 | next += 1;
45 | res.send(201, json);
46 | });
47 |
48 | tracksRouter.get('/:id', function(req, res) {
49 | res.send({
50 | 'tracks': {
51 | id: FIXTURES.filter(function (track) {
52 | return track.id == req.params.id;
53 | })[0]
54 | }
55 | });
56 | });
57 |
58 | tracksRouter.put('/:id', function(req, res) {
59 | res.send({
60 | 'tracks': {
61 | id: req.params.id
62 | }
63 | });
64 | });
65 |
66 | tracksRouter.delete('/:id', function(req, res) {
67 | res.status(204).end();
68 | });
69 |
70 | app.use(require('body-parser').json());
71 | app.use('/api/tracks', tracksRouter);
72 | };
73 |
--------------------------------------------------------------------------------