From 5193ddc72f16958a52a1d6f4cfc3787d3a0a6be6 Mon Sep 17 00:00:00 2001
From: Robin Ward <robin.ward@gmail.com>
Date: Thu, 13 Jun 2013 15:08:42 -0400
Subject: [PATCH] Super basic test support for listing topics

---
 app/assets/javascripts/discourse.js           |  9 +++++
 .../javascripts/discourse/models/nav_item.js  | 13 +++++--
 .../discourse/models/topic_list.js            | 36 +++++++++++--------
 config/jshint.yml                             |  1 +
 sublime-project                               |  3 +-
 test/javascripts/fixtures/list.js             |  3 ++
 test/javascripts/fixtures/site_settings.js    |  2 ++
 test/javascripts/integration/header_test.js   |  5 +--
 .../integration/list_topics_test.js           | 23 ++++++++++++
 test/javascripts/test_helper.js               | 17 ++++++---
 10 files changed, 88 insertions(+), 24 deletions(-)
 create mode 100644 test/javascripts/fixtures/list.js
 create mode 100644 test/javascripts/fixtures/site_settings.js
 create mode 100644 test/javascripts/integration/list_topics_test.js

diff --git a/app/assets/javascripts/discourse.js b/app/assets/javascripts/discourse.js
index 6c18fe5bb..a6e831349 100644
--- a/app/assets/javascripts/discourse.js
+++ b/app/assets/javascripts/discourse.js
@@ -225,6 +225,7 @@ Discourse = Ember.Application.createWithMixins({
   ajax: function() {
 
     var url, args;
+
     if (arguments.length === 1) {
       if (typeof arguments[0] === "string") {
         url = arguments[0];
@@ -246,6 +247,14 @@ Discourse = Ember.Application.createWithMixins({
       console.warning("DEPRECATION: Discourse.ajax should use promises, received 'error' callback");
     }
 
+    // If we have URL_FIXTURES, load from there instead (testing)
+    var fixture = Discourse.URL_FIXTURES && Discourse.URL_FIXTURES[url];
+    if (fixture) {
+      return Ember.Deferred.promise(function(promise) {
+        promise.resolve(fixture);
+      })
+    }
+
     return Ember.Deferred.promise(function (promise) {
       var oldSuccess = args.success;
       args.success = function(xhr) {
diff --git a/app/assets/javascripts/discourse/models/nav_item.js b/app/assets/javascripts/discourse/models/nav_item.js
index 4b1e9e28e..ead576286 100644
--- a/app/assets/javascripts/discourse/models/nav_item.js
+++ b/app/assets/javascripts/discourse/models/nav_item.js
@@ -10,7 +10,8 @@ var validNavNames = ['latest', 'hot', 'categories', 'category', 'favorited', 'un
 var validAnon     = ['latest', 'hot', 'categories', 'category'];
 
 Discourse.NavItem = Discourse.Model.extend({
-  topicTrackingState: function(){
+
+  topicTrackingState: function() {
     return Discourse.TopicTrackingState.current();
   }.property(),
 
@@ -32,7 +33,15 @@ Discourse.NavItem = Discourse.Model.extend({
     if (state) {
       return state.lookupCount(this.get('name'));
     }
-  }.property('topicTrackingState.messageCount')
+  }.property('topicTrackingState.messageCount'),
+
+  excludeCategory: function() {
+    if (parseInt(this.get('filters.length'), 10) > 0) {
+      return this.get('filters')[0].substring(1);
+    }
+  }.property('filters.length')
+
+
 });
 
 Discourse.NavItem.reopenClass({
diff --git a/app/assets/javascripts/discourse/models/topic_list.js b/app/assets/javascripts/discourse/models/topic_list.js
index 3563e11c3..179f21864 100644
--- a/app/assets/javascripts/discourse/models/topic_list.js
+++ b/app/assets/javascripts/discourse/models/topic_list.js
@@ -120,17 +120,7 @@ Discourse.TopicList.reopenClass({
   },
 
   list: function(menuItem) {
-    var filter = menuItem.name;
-
-    var topicList = Discourse.TopicList.create({
-      inserted: Em.A(),
-      filter: filter
-    });
-
-    var url = Discourse.getURL("/") + filter + ".json";
-    if (menuItem.filters && menuItem.filters.length > 0) {
-      url += "?exclude_category=" + menuItem.filters[0].substring(1);
-    }
+    var filter = menuItem.get('name');
 
     var list = Discourse.get('transient.topicsList');
     if (list) {
@@ -144,8 +134,26 @@ Discourse.TopicList.reopenClass({
     Discourse.set('transient.topicsList', null);
     Discourse.set('transient.topicListScrollPos', null);
 
-    return PreloadStore.getAndRemove("topic_list", function() { return Discourse.ajax(url) }).then(function(result) {
-      topicList.setProperties({
+    return Discourse.TopicList.find(filter, menuItem.get('excludeCategory'));
+  }
+});
+
+
+Discourse.TopicList.reopenClass({
+
+  find: function(filter, excludeCategory) {
+
+    // How we find our topic list
+    var finder = function() {
+      var url = Discourse.getURL("/") + filter + ".json";
+      if (excludeCategory) { url += "?exclude_category=" + excludeCategory; }
+      return Discourse.ajax(url);
+    }
+
+    return PreloadStore.getAndRemove("topic_list", finder).then(function(result) {
+      var topicList = Discourse.TopicList.create({
+        inserted: Em.A(),
+        filter: filter,
         topics: Discourse.TopicList.topicsFrom(result),
         can_create_topic: result.topic_list.can_create_topic,
         more_topics_url: result.topic_list.more_topics_url,
@@ -162,6 +170,6 @@ Discourse.TopicList.reopenClass({
       return topicList;
     });
   }
+
 });
 
-
diff --git a/config/jshint.yml b/config/jshint.yml
index 3cf9edc46..5f75dc0a2 100644
--- a/config/jshint.yml
+++ b/config/jshint.yml
@@ -10,6 +10,7 @@ paths:
   - app/assets/javascripts/**/*.js
   - spec/javascripts/**/*.js
   - spec/phantom_js/**/*.js
+  - test/javascripts/**/*.js
 
 exclude_paths:
   - app/assets/javascripts/external/*
diff --git a/sublime-project b/sublime-project
index 1c37118bd..5c30c111d 100644
--- a/sublime-project
+++ b/sublime-project
@@ -14,7 +14,8 @@
     { "path": "lib" },
     { "path": "script" },
     { "path": "cookbooks" },
-    { "path": "spec" }
+    { "path": "spec" },
+    { "path": "test" }
   ],
   "settings":
   {
diff --git a/test/javascripts/fixtures/list.js b/test/javascripts/fixtures/list.js
new file mode 100644
index 000000000..48a94c823
--- /dev/null
+++ b/test/javascripts/fixtures/list.js
@@ -0,0 +1,3 @@
+/*jshint maxlen:10000000 */
+Discourse.URL_FIXTURES = Discourse.URL_FIXTURES || {};
+Discourse.URL_FIXTURES["/latest.json"] = {"categories":[{"id":1,"name":"bug","color":"ae3a27","text_color":"FFFFFF","slug":"bug","topic_count":338,"description":"&gt; Bug reports on Discourse. Please be sure to search prior to submitting bugs. Please include repro steps, and report only 1 bug per topic.","topic_url":"/t/category-definition-for-bug/2","hotness":5.0,"secure":false},{"id":2,"name":"feature","color":"0E76BD","text_color":"FFFFFF","slug":"feature","topic_count":354,"description":"Discussion about features or potential features of Discourse: how they work, why they work, etc.","topic_url":"/t/category-definition-for-feature/11","hotness":5.0,"secure":false},{"id":3,"name":"meta","color":"aaa","text_color":"FFFFFF","slug":"meta","topic_count":59,"description":"Discussion about meta.discourse.org itself, the organization of this forum about Discourse, how it works, and how we can improve this site.","topic_url":"/t/category-definition-for-meta/24","hotness":5.0,"secure":false},{"id":12,"name":"discourse hub","color":"b2c79f","text_color":"FFFFFF","slug":"discourse-hub","topic_count":4,"description":"Topics about current or future Discourse Hub functionality at discourse.org including nickname registration, global user pages, and the site directory.","topic_url":"/t/category-definition-for-discourse-hub/3038","hotness":5.0,"secure":false},{"id":7,"name":"dev","color":"000","text_color":"FFFFFF","slug":"dev","topic_count":157,"description":"This category is for topics related to hacking on Discourse: submitting pull requests, configuring development environments, coding conventions, and so forth.","topic_url":"/t/category-definition-for-dev/1026","hotness":5.0,"secure":false},{"id":9,"name":"ux","color":"5F497A","text_color":"FFFFFF","slug":"ux","topic_count":88,"description":"Discussion about the user interface of Discourse, how features are presented to the user in the client, including language and UI elements.","topic_url":"/t/category-definition-for-ux/2628","hotness":5.0,"secure":false},{"id":5,"name":"extensibility ","color":"FE8432","text_color":"FFFFFF","slug":"extensibility","topic_count":26,"description":"Topics about extending the functionality of Discourse with plugins, themes, add-ons, or other mechanisms for extensibility.  ","topic_url":"/t/category-definition-for-extensibility/28","hotness":5.0,"secure":false},{"id":6,"name":"support","color":"b99","text_color":"FFFFFF","slug":"support","topic_count":276,"description":"Support on configuring, using, and installing Discourse. Not for software development related topics, but for admins and end users configuring and using Discourse.","topic_url":"/t/category-definition-for-support/389","hotness":5.0,"secure":false},{"id":4,"name":"faq","color":"33b","text_color":"FFFFFF","slug":"faq","topic_count":38,"description":"Topics that come up very often when discussing Discourse will eventually be classified into this Frequently Asked Questions category. Should only be added to popular topics.","topic_url":"/t/category-definition-for-faq/25","hotness":5.0,"secure":false}],"users":[{"id":1,"username":"sam","avatar_template":"https://www.gravatar.com/avatar/3dcae8378d46c244172a115c28ca49ce.png?s={size}&r=pg&d=identicon"},{"id":19,"username":"eviltrout","avatar_template":"https://www.gravatar.com/avatar/c6e17f2ae2a215e87ff9e878a4e63cd9.png?s={size}&r=pg&d=identicon"},{"id":14,"username":"clay","avatar_template":"https://www.gravatar.com/avatar/e371bbd32ba2e9b27842e60ef5952d47.png?s={size}&r=pg&d=identicon"},{"id":32,"username":"codinghorror","avatar_template":"https://www.gravatar.com/avatar/51d623f33f8b83095db84ff35e15dbe8.png?s={size}&r=pg&d=identicon"},{"id":5483,"username":"briangillespie","avatar_template":"https://www.gravatar.com/avatar/3baf9989e97ccf45aff1cf61fb730931.png?s={size}&r=pg&d=identicon"},{"id":4757,"username":"cerberus","avatar_template":"https://www.gravatar.com/avatar/cf99a7295aafa43c75ce25668b24df29.png?s={size}&r=pg&d=identicon"},{"id":247,"username":"chrishunt","avatar_template":"https://www.gravatar.com/avatar/4fafaca2401263fd03b62ff37a157a35.png?s={size}&r=pg&d=identicon"},{"id":406,"username":"RGJ","avatar_template":"https://www.gravatar.com/avatar/55c791f0242e5167536c65496046eef5.png?s={size}&r=pg&d=identicon"},{"id":38,"username":"frandallfarmer","avatar_template":"https://www.gravatar.com/avatar/6c38e00d92cd9bd3ada3392b15015553.png?s={size}&r=pg&d=identicon"},{"id":5425,"username":"mattengi","avatar_template":"https://www.gravatar.com/avatar/b66610f025dda14e96453bc5a0124685.png?s={size}&r=pg&d=identicon"},{"id":562,"username":"nightpool","avatar_template":"https://www.gravatar.com/avatar/d73164d2180b4cf6099526e42e33a7fd.png?s={size}&r=pg&d=identicon"},{"id":4939,"username":"stevebaer","avatar_template":"https://www.gravatar.com/avatar/7a42855912a58f4c3c5d0ce82e33905f.png?s={size}&r=pg&d=identicon"},{"id":761,"username":"marcoceppi","avatar_template":"https://www.gravatar.com/avatar/4ddc8924e79bcec03256821af65fca91.png?s={size}&r=pg&d=identicon"},{"id":1681,"username":"juanformoso","avatar_template":"https://www.gravatar.com/avatar/4dfc8f56817006ef21327d5ff19ce04f.png?s={size}&r=pg&d=identicon"},{"id":4612,"username":"Iszi","avatar_template":"https://www.gravatar.com/avatar/8f8571493d71202986f2a6ab0dbd7c23.png?s={size}&r=pg&d=identicon"},{"id":1995,"username":"zogstrip","avatar_template":"https://www.gravatar.com/avatar/b7797beb47cfb7aa0fe60d09604aaa09.png?s={size}&r=pg&d=identicon"},{"id":1219,"username":"Gweebz","avatar_template":"https://www.gravatar.com/avatar/62e7d47ca49b942923f36eb90c1a31bd.png?s={size}&r=pg&d=identicon"},{"id":388,"username":"Drew","avatar_template":"https://www.gravatar.com/avatar/12b37360428acef73ff2c29cd3f272ef.png?s={size}&r=pg&d=identicon"},{"id":1566,"username":"hamburglar","avatar_template":"https://www.gravatar.com/avatar/57b39f59fa025f64e173ba6dffb8f2f7.png?s={size}&r=pg&d=identicon"},{"id":2,"username":"Neil","avatar_template":"https://www.gravatar.com/avatar/42776c4982dff1fa45ee8248532f8ad0.png?s={size}&r=pg&d=identicon"},{"id":5382,"username":"Charlie","avatar_template":"https://www.gravatar.com/avatar/4ae31ca93cd8a41fb44dace9d9d65166.png?s={size}&r=pg&d=identicon"},{"id":5372,"username":"computerdruid","avatar_template":"https://www.gravatar.com/avatar/34c3b45c075a6d85555beb674892d0d8.png?s={size}&r=pg&d=identicon"},{"id":1263,"username":"ChrisB","avatar_template":"https://www.gravatar.com/avatar/1d75aba12b3961894f93959b5b013de0.png?s={size}&r=pg&d=identicon"},{"id":5438,"username":"hpesoj","avatar_template":"https://www.gravatar.com/avatar/c6f01bdb4443d3686d8a11d8899c0100.png?s={size}&r=pg&d=identicon"},{"id":2770,"username":"awesomerobot","avatar_template":"https://www.gravatar.com/avatar/9744a2573a43bb6d76deef82b7424023.png?s={size}&r=pg&d=identicon"},{"id":5174,"username":"Maria_Sergeeva","avatar_template":"https://www.gravatar.com/avatar/3e8ede783ef16c8234c03473a5b8780f.png?s={size}&r=pg&d=identicon"},{"id":2291,"username":"PabloC","avatar_template":"https://www.gravatar.com/avatar/82c793022ec1bce6ea7573bc27b2340b.png?s={size}&r=pg&d=identicon"},{"id":3657,"username":"steelmaiden","avatar_template":"https://www.gravatar.com/avatar/ee057e3db79dbbf327ee1e2d3af3320d.png?s={size}&r=pg&d=identicon"},{"id":5502,"username":"ankursethi108","avatar_template":"https://www.gravatar.com/avatar/da27d97199c2e567ff848bf70984d405.png?s={size}&r=pg&d=identicon"},{"id":5271,"username":"royguo","avatar_template":"https://www.gravatar.com/avatar/7e795755fe8a817981c3a81620faf359.png?s={size}&r=pg&d=identicon"},{"id":2063,"username":"amoiseev","avatar_template":"https://www.gravatar.com/avatar/56c19d0f5d2640d4ddf730e25acf4364.png?s={size}&r=pg&d=identicon"},{"id":3987,"username":"Sander78","avatar_template":"https://www.gravatar.com/avatar/e7069beb46df22270a41afc7b277fe50.png?s={size}&r=pg&d=identicon"},{"id":3,"username":"supermathie","avatar_template":"https://www.gravatar.com/avatar/44ae1b2d44d48aed3d432129a5703942.png?s={size}&r=pg&d=identicon"},{"id":4220,"username":"kirantpatil","avatar_template":"https://www.gravatar.com/avatar/99d5ef2d7a453192340ca2c8adc21aa9.png?s={size}&r=pg&d=identicon"},{"id":471,"username":"BhaelOchon","avatar_template":"https://www.gravatar.com/avatar/413ef976f0d2ca993005c9aee4769254.png?s={size}&r=pg&d=identicon"},{"id":2316,"username":"pakl","avatar_template":"https://www.gravatar.com/avatar/42910619ef3d550e37f7150caa0d94ff.png?s={size}&r=pg&d=identicon"},{"id":5293,"username":"nick12377","avatar_template":"https://www.gravatar.com/avatar/de9a910f6c145938e047f77a524df50b.png?s={size}&r=pg&d=identicon"},{"id":1374,"username":"naggie","avatar_template":"https://www.gravatar.com/avatar/43675ac6f4ef94f40b5e44add2a984c1.png?s={size}&r=pg&d=identicon"}],"topic_list":{"can_create_topic":false,"more_topics_url":"/latest.json?page=1","draft":null,"draft_key":"new_topic","draft_sequence":null,"topics":[{"id":1,"fancy_title":"Welcome to meta.discourse.org","slug":"welcome-to-meta-discourse-org","posts_count":5,"reply_count":5,"highest_post_number":23,"image_url":null,"created_at":"2013-01-31T23:52:28-05:00","last_posted_at":"2013-02-07T16:50:41-05:00","bumped":true,"bumped_at":"2013-02-07T11:57:34-05:00","unseen":false,"title":"Welcome to meta.discourse.org","pinned":true,"excerpt":"Welcome to meta, the official site for discussing the next-gen open source Discourse forum software. You&#x27;ll find topics on features, bugs, hosting, development, and general support here. \n\nDiscourse is early beta softwar&hellip;","visible":true,"closed":true,"archived":false,"views":9279,"like_count":84,"has_best_of":false,"archetype":"regular","category_id":null,"posters":[{"extras":null,"description":"Original Poster","user_id":1},{"extras":null,"description":"Most Posts","user_id":19},{"extras":null,"description":"Frequent Poster","user_id":14},{"extras":"latest","description":"Most Recent Poster","user_id":32}]},{"id":7418,"fancy_title":"Auto-suggest topics shows Private topics","slug":"auto-suggest-topics-shows-private-topics","posts_count":2,"reply_count":1,"highest_post_number":2,"image_url":null,"created_at":"2013-06-12T12:08:11-04:00","last_posted_at":"2013-06-12T12:32:08-04:00","bumped":true,"bumped_at":"2013-06-12T12:32:08-04:00","unseen":false,"title":"Auto-suggest topics shows Private topics","pinned":false,"visible":true,"closed":false,"archived":false,"views":7,"like_count":0,"has_best_of":false,"archetype":"regular","category_id":1,"posters":[{"extras":null,"description":"Original Poster","user_id":5483},{"extras":"latest","description":"Most Recent Poster","user_id":32}]},{"id":7392,"fancy_title":"It there user&rsquo;s birthday in user profile?","slug":"it-there-users-birthday-in-user-profile","posts_count":5,"reply_count":2,"highest_post_number":5,"image_url":null,"created_at":"2013-06-11T19:02:05-04:00","last_posted_at":"2013-06-12T12:23:06-04:00","bumped":true,"bumped_at":"2013-06-12T12:23:06-04:00","unseen":false,"title":"It there user's birthday in user profile?","pinned":false,"visible":true,"closed":false,"archived":false,"views":42,"like_count":2,"has_best_of":false,"archetype":"regular","category_id":2,"posters":[{"extras":"latest","description":"Original Poster, Most Recent Poster","user_id":4757},{"extras":null,"description":"Most Posts","user_id":247},{"extras":null,"description":"Frequent Poster","user_id":1},{"extras":null,"description":"Frequent Poster","user_id":406}]},{"id":7420,"fancy_title":"Federated login for Microsoft and Apple","slug":"federated-login-for-microsoft-and-apple","posts_count":1,"reply_count":0,"highest_post_number":1,"image_url":null,"created_at":"2013-06-12T12:19:23-04:00","last_posted_at":"2013-06-12T12:19:24-04:00","bumped":true,"bumped_at":"2013-06-12T12:19:24-04:00","unseen":false,"title":"Federated login for Microsoft and Apple","pinned":false,"visible":true,"closed":false,"archived":false,"views":4,"like_count":0,"has_best_of":false,"archetype":"regular","category_id":2,"posters":[{"extras":"latest","description":"Original Poster, Most Recent Poster","user_id":5483}]},{"id":3102,"fancy_title":"Please visit our Discourse Forum! (Directory)","slug":"please-visit-our-discourse-forum-directory","posts_count":36,"reply_count":16,"highest_post_number":36,"image_url":null,"created_at":"2013-02-14T14:30:38-05:00","last_posted_at":"2013-06-12T12:18:41-04:00","bumped":true,"bumped_at":"2013-06-12T12:18:41-04:00","unseen":false,"title":"Please visit our Discourse Forum! (Directory)","pinned":false,"visible":true,"closed":false,"archived":false,"views":2458,"like_count":32,"has_best_of":false,"archetype":"regular","category_id":3,"posters":[{"extras":null,"description":"Original Poster","user_id":38},{"extras":null,"description":"Most Posts","user_id":5425},{"extras":null,"description":"Frequent Poster","user_id":32},{"extras":null,"description":"Frequent Poster","user_id":562},{"extras":"latest","description":"Most Recent Poster","user_id":4939}]},{"id":7419,"fancy_title":"Non-authenticated users see all topics in mobile view","slug":"non-authenticated-users-see-all-topics-in-mobile-view","posts_count":1,"reply_count":0,"highest_post_number":1,"image_url":null,"created_at":"2013-06-12T12:11:13-04:00","last_posted_at":"2013-06-12T12:11:14-04:00","bumped":true,"bumped_at":"2013-06-12T12:11:14-04:00","unseen":false,"title":"Non-authenticated users see all topics in mobile view","pinned":false,"visible":true,"closed":false,"archived":false,"views":4,"like_count":1,"has_best_of":false,"archetype":"regular","category_id":1,"posters":[{"extras":"latest","description":"Original Poster, Most Recent Poster","user_id":5483}]},{"id":7417,"fancy_title":"Oneboxing &ldquo;non-traditional&rdquo; URLs","slug":"oneboxing-non-traditional-urls","posts_count":1,"reply_count":0,"highest_post_number":1,"image_url":null,"created_at":"2013-06-12T11:42:19-04:00","last_posted_at":"2013-06-12T11:42:20-04:00","bumped":true,"bumped_at":"2013-06-12T11:42:20-04:00","unseen":false,"title":"Oneboxing \"non-traditional\" URLs","pinned":false,"visible":true,"closed":false,"archived":false,"views":13,"like_count":0,"has_best_of":false,"archetype":"regular","category_id":2,"posters":[{"extras":"latest","description":"Original Poster, Most Recent Poster","user_id":761}]},{"id":7411,"fancy_title":"Unable to send digests","slug":"unable-to-send-digests","posts_count":12,"reply_count":7,"highest_post_number":12,"image_url":"http://cdn.discourse.org/uploads/meta_discourse/1078/030dd27562e8cc64.png","created_at":"2013-06-12T09:25:21-04:00","last_posted_at":"2013-06-12T11:21:10-04:00","bumped":true,"bumped_at":"2013-06-12T11:34:35-04:00","unseen":false,"title":"Unable to send digests","pinned":false,"visible":true,"closed":false,"archived":false,"views":26,"like_count":0,"has_best_of":false,"archetype":"regular","category_id":1,"posters":[{"extras":"latest","description":"Original Poster, Most Recent Poster","user_id":1681},{"extras":null,"description":"Most Posts","user_id":19},{"extras":null,"description":"Frequent Poster","user_id":1}]},{"id":6130,"fancy_title":"Make it easier to close large images","slug":"make-it-easier-to-close-large-images","posts_count":10,"reply_count":6,"highest_post_number":10,"image_url":null,"created_at":"2013-04-24T11:35:04-04:00","last_posted_at":"2013-06-12T11:26:21-04:00","bumped":true,"bumped_at":"2013-06-12T11:26:21-04:00","unseen":false,"title":"Make it easier to close large images","pinned":false,"visible":true,"closed":false,"archived":false,"views":124,"like_count":6,"has_best_of":false,"archetype":"regular","category_id":null,"posters":[{"extras":"latest","description":"Original Poster, Most Recent Poster","user_id":4612},{"extras":null,"description":"Most Posts","user_id":1995},{"extras":null,"description":"Frequent Poster","user_id":32},{"extras":null,"description":"Frequent Poster","user_id":1219}]},{"id":424,"fancy_title":"What are the &lsquo;consequences&rsquo; of changing your name?","slug":"what-are-the-consequences-of-changing-your-name","posts_count":34,"reply_count":31,"highest_post_number":34,"image_url":null,"created_at":"2013-02-05T17:37:52-05:00","last_posted_at":"2013-06-12T10:56:54-04:00","bumped":true,"bumped_at":"2013-06-12T10:56:54-04:00","unseen":false,"title":"What are the 'consequences' of changing your name?","pinned":false,"visible":true,"closed":false,"archived":false,"views":953,"like_count":41,"has_best_of":false,"archetype":"regular","category_id":12,"posters":[{"extras":null,"description":"Original Poster","user_id":388},{"extras":null,"description":"Most Posts","user_id":1566},{"extras":null,"description":"Frequent Poster","user_id":32},{"extras":null,"description":"Frequent Poster","user_id":2},{"extras":"latest","description":"Most Recent Poster","user_id":5382}]},{"id":7410,"fancy_title":"Twitter oneboxes are bust","slug":"twitter-oneboxes-are-bust","posts_count":2,"reply_count":0,"highest_post_number":2,"image_url":null,"created_at":"2013-06-12T07:19:42-04:00","last_posted_at":"2013-06-12T10:50:31-04:00","bumped":true,"bumped_at":"2013-06-12T10:50:31-04:00","unseen":false,"title":"Twitter oneboxes are bust","pinned":false,"visible":true,"closed":false,"archived":false,"views":31,"like_count":0,"has_best_of":false,"archetype":"regular","category_id":1,"posters":[{"extras":null,"description":"Original Poster","user_id":1},{"extras":"latest","description":"Most Recent Poster","user_id":5372}]},{"id":7403,"fancy_title":"Deploy Disource at local machine with juju, lxc","slug":"deploy-disource-at-local-machine-with-juju-lxc","posts_count":7,"reply_count":4,"highest_post_number":7,"image_url":"http://cdn.discourse.org/assets/emoji/rage.png","created_at":"2013-06-11T23:23:09-04:00","last_posted_at":"2013-06-12T10:37:03-04:00","bumped":true,"bumped_at":"2013-06-12T10:37:03-04:00","unseen":false,"title":"Deploy Disource at local machine with juju, lxc","pinned":false,"visible":true,"closed":false,"archived":false,"views":32,"like_count":3,"has_best_of":false,"archetype":"regular","category_id":7,"posters":[{"extras":null,"description":"Original Poster","user_id":5425},{"extras":null,"description":"Most Posts","user_id":1},{"extras":"latest","description":"Most Recent Poster","user_id":761}]},{"id":7362,"fancy_title":"Should post date/times be moved to remove ambiguity between user join dates or activity?","slug":"should-post-date-times-be-moved-to-remove-ambiguity-between-user-join-dates-or-activity","posts_count":23,"reply_count":18,"highest_post_number":23,"image_url":"https://www.gravatar.com/avatar/51d623f33f8b83095db84ff35e15dbe8.png?s=40&r=pg&d=identicon","created_at":"2013-06-10T18:52:34-04:00","last_posted_at":"2013-06-12T10:35:29-04:00","bumped":true,"bumped_at":"2013-06-12T10:35:29-04:00","unseen":false,"title":"Should post date/times be moved to remove ambiguity between user join dates or activity?","pinned":false,"visible":true,"closed":false,"archived":false,"views":114,"like_count":9,"has_best_of":false,"archetype":"regular","category_id":9,"posters":[{"extras":"latest","description":"Original Poster, Most Recent Poster","user_id":1263},{"extras":null,"description":"Most Posts","user_id":32},{"extras":null,"description":"Frequent Poster","user_id":1},{"extras":null,"description":"Frequent Poster","user_id":5438},{"extras":null,"description":"Frequent Poster","user_id":2770}]},{"id":7412,"fancy_title":"To group posts by a user","slug":"to-group-posts-by-a-user","posts_count":3,"reply_count":2,"highest_post_number":3,"image_url":null,"created_at":"2013-06-12T09:35:57-04:00","last_posted_at":"2013-06-12T10:06:38-04:00","bumped":true,"bumped_at":"2013-06-12T10:14:51-04:00","unseen":false,"title":"To group posts by a user","pinned":false,"visible":true,"closed":false,"archived":false,"views":16,"like_count":3,"has_best_of":false,"archetype":"regular","category_id":2,"posters":[{"extras":"latest","description":"Original Poster, Most Recent Poster","user_id":5174},{"extras":null,"description":"Most Posts","user_id":1}]},{"id":5689,"fancy_title":"Wordpress plugin to include latest topics as a sidebar?","slug":"wordpress-plugin-to-include-latest-topics-as-a-sidebar","posts_count":3,"reply_count":0,"highest_post_number":3,"image_url":null,"created_at":"2013-04-07T16:08:21-04:00","last_posted_at":"2013-06-12T09:58:21-04:00","bumped":true,"bumped_at":"2013-06-12T09:58:21-04:00","unseen":false,"title":"Wordpress plugin to include latest topics as a sidebar?","pinned":false,"visible":true,"closed":false,"archived":false,"views":139,"like_count":0,"has_best_of":false,"archetype":"regular","category_id":5,"posters":[{"extras":null,"description":"Original Poster","user_id":2291},{"extras":null,"description":"Most Posts","user_id":3657},{"extras":"latest","description":"Most Recent Poster","user_id":5502}]},{"id":7401,"fancy_title":"Shall we add category names in top_menu?","slug":"shall-we-add-category-names-in-top-menu","posts_count":7,"reply_count":4,"highest_post_number":7,"image_url":null,"created_at":"2013-06-11T22:47:34-04:00","last_posted_at":"2013-06-12T06:55:03-04:00","bumped":true,"bumped_at":"2013-06-12T06:55:03-04:00","unseen":false,"title":"Shall we add category names in top_menu?","pinned":false,"visible":true,"closed":false,"archived":false,"views":35,"like_count":1,"has_best_of":false,"archetype":"regular","category_id":1,"posters":[{"extras":"latest","description":"Original Poster, Most Recent Poster","user_id":5271},{"extras":null,"description":"Most Posts","user_id":1}]},{"id":7393,"fancy_title":"Cannot click on image immediately after uploading","slug":"cannot-click-on-image-immediately-after-uploading","posts_count":3,"reply_count":1,"highest_post_number":3,"image_url":null,"created_at":"2013-06-11T19:05:32-04:00","last_posted_at":"2013-06-12T06:15:02-04:00","bumped":true,"bumped_at":"2013-06-12T06:15:02-04:00","unseen":false,"title":"Cannot click on image immediately after uploading","pinned":false,"visible":true,"closed":false,"archived":false,"views":24,"like_count":0,"has_best_of":false,"archetype":"regular","category_id":1,"posters":[{"extras":"latest","description":"Original Poster, Most Recent Poster","user_id":5438},{"extras":null,"description":"Most Posts","user_id":1995}]},{"id":7391,"fancy_title":"Upload image button doesn&rsquo;t work after uploading an image","slug":"upload-image-button-doesnt-work-after-uploading-an-image","posts_count":3,"reply_count":1,"highest_post_number":3,"image_url":null,"created_at":"2013-06-11T19:01:56-04:00","last_posted_at":"2013-06-12T06:14:01-04:00","bumped":true,"bumped_at":"2013-06-12T06:14:01-04:00","unseen":false,"title":"Upload image button doesn't work after uploading an image","pinned":false,"visible":true,"closed":false,"archived":false,"views":22,"like_count":0,"has_best_of":false,"archetype":"regular","category_id":1,"posters":[{"extras":"latest","description":"Original Poster, Most Recent Poster","user_id":5438},{"extras":null,"description":"Most Posts","user_id":1995}]},{"id":7409,"fancy_title":"New Relic installation","slug":"new-relic-installation","posts_count":3,"reply_count":2,"highest_post_number":3,"image_url":null,"created_at":"2013-06-12T05:11:58-04:00","last_posted_at":"2013-06-12T05:20:30-04:00","bumped":true,"bumped_at":"2013-06-12T05:20:30-04:00","unseen":false,"title":"New Relic installation","pinned":false,"visible":true,"closed":false,"archived":false,"views":22,"like_count":0,"has_best_of":false,"archetype":"regular","category_id":6,"posters":[{"extras":"latest","description":"Original Poster, Most Recent Poster","user_id":2063},{"extras":null,"description":"Most Posts","user_id":3987}]},{"id":7405,"fancy_title":"How to add &ldquo;/faq&rdquo; link in top menu?","slug":"how-to-add-faq-link-in-top-menu","posts_count":1,"reply_count":0,"highest_post_number":1,"image_url":null,"created_at":"2013-06-12T01:28:32-04:00","last_posted_at":"2013-06-12T01:28:32-04:00","bumped":true,"bumped_at":"2013-06-12T03:12:30-04:00","unseen":false,"title":"How to add \"/faq\" link in top menu?","pinned":false,"visible":true,"closed":false,"archived":false,"views":31,"like_count":0,"has_best_of":false,"archetype":"regular","category_id":6,"posters":[{"extras":"latest","description":"Original Poster, Most Recent Poster","user_id":5271}]},{"id":7408,"fancy_title":"What are the options for hammering a bad account?","slug":"what-are-the-options-for-hammering-a-bad-account","posts_count":1,"reply_count":0,"highest_post_number":1,"image_url":"http://cdn.discourse.org/uploads/meta_discourse/1077/43066a4fc47d1d70.png","created_at":"2013-06-12T02:33:53-04:00","last_posted_at":"2013-06-12T02:33:53-04:00","bumped":false,"bumped_at":"2013-06-12T02:33:53-04:00","unseen":false,"title":"What are the options for hammering a bad account?","pinned":false,"visible":true,"closed":false,"archived":false,"views":26,"like_count":0,"has_best_of":false,"archetype":"regular","category_id":null,"posters":[{"extras":"latest","description":"Original Poster, Most Recent Poster","user_id":3}]},{"id":7378,"fancy_title":"Discourse Release Announcements for each tagged version release","slug":"discourse-release-announcements-for-each-tagged-version-release","posts_count":5,"reply_count":2,"highest_post_number":5,"image_url":null,"created_at":"2013-06-11T10:31:03-04:00","last_posted_at":"2013-06-12T02:18:33-04:00","bumped":true,"bumped_at":"2013-06-12T02:18:33-04:00","unseen":false,"title":"Discourse Release Announcements for each tagged version release","pinned":false,"visible":true,"closed":false,"archived":false,"views":79,"like_count":7,"has_best_of":false,"archetype":"regular","category_id":4,"posters":[{"extras":null,"description":"Original Poster","user_id":4220},{"extras":null,"description":"Most Posts","user_id":471},{"extras":null,"description":"Frequent Poster","user_id":32},{"extras":null,"description":"Frequent Poster","user_id":1},{"extras":"latest","description":"Most Recent Poster","user_id":761}]},{"id":7406,"fancy_title":"[missing {{user}} value] in user&rsquo;s home page","slug":"missing-user-value-in-users-home-page","posts_count":3,"reply_count":2,"highest_post_number":3,"image_url":"http://cdn.discourse.org/uploads/meta_discourse/1074/09013263c0ffc523.png","created_at":"2013-06-12T01:32:04-04:00","last_posted_at":"2013-06-12T01:47:03-04:00","bumped":true,"bumped_at":"2013-06-12T01:47:03-04:00","unseen":false,"title":"[missing {{user}} value] in user's home page","pinned":false,"visible":true,"closed":false,"archived":false,"views":17,"like_count":0,"has_best_of":false,"archetype":"regular","category_id":1,"posters":[{"extras":"latest","description":"Original Poster, Most Recent Poster","user_id":5271},{"extras":null,"description":"Most Posts","user_id":1}]},{"id":7400,"fancy_title":"Mockups/Ideas for extended profiles","slug":"mockups-ideas-for-extended-profiles","posts_count":2,"reply_count":1,"highest_post_number":2,"image_url":"http://cdn.discourse.org/uploads/meta_discourse/1061/8a6ac964893019ea.png","created_at":"2013-06-11T22:14:03-04:00","last_posted_at":"2013-06-12T01:01:26-04:00","bumped":true,"bumped_at":"2013-06-12T01:01:26-04:00","unseen":false,"title":"Mockups/Ideas for extended profiles","pinned":false,"visible":true,"closed":false,"archived":false,"views":34,"like_count":0,"has_best_of":false,"archetype":"regular","category_id":9,"posters":[{"extras":null,"description":"Original Poster","user_id":2316},{"extras":"latest","description":"Most Recent Poster","user_id":1}]},{"id":7146,"fancy_title":"Getting rid of sugar.js","slug":"getting-rid-of-sugar-js","posts_count":4,"reply_count":1,"highest_post_number":4,"image_url":null,"created_at":"2013-06-04T03:22:49-04:00","last_posted_at":"2013-06-11T23:50:46-04:00","bumped":true,"bumped_at":"2013-06-11T23:50:46-04:00","unseen":false,"title":"Getting rid of sugar.js","pinned":false,"visible":true,"closed":false,"archived":false,"views":133,"like_count":8,"has_best_of":false,"archetype":"regular","category_id":7,"posters":[{"extras":"latest","description":"Original Poster, Most Recent Poster","user_id":1},{"extras":null,"description":"Most Posts","user_id":19},{"extras":null,"description":"Frequent Poster","user_id":2}]},{"id":7397,"fancy_title":"Incorrect string in new posts counter tooltip","slug":"incorrect-string-in-new-posts-counter-tooltip","posts_count":4,"reply_count":1,"highest_post_number":4,"image_url":"http://i.imgur.com/7557h94.png","created_at":"2013-06-11T21:15:40-04:00","last_posted_at":"2013-06-11T22:25:04-04:00","bumped":true,"bumped_at":"2013-06-11T22:11:00-04:00","unseen":false,"title":"Incorrect string in new posts counter tooltip","pinned":false,"visible":true,"closed":false,"archived":true,"views":19,"like_count":0,"has_best_of":false,"archetype":"regular","category_id":1,"posters":[{"extras":null,"description":"Original Poster","user_id":5425},{"extras":"latest","description":"Most Recent Poster, Most Posts","user_id":1}]},{"id":7390,"fancy_title":"&ldquo;Topic_count&rdquo; instead of actual count","slug":"topic-count-instead-of-actual-count","posts_count":3,"reply_count":0,"highest_post_number":3,"image_url":"http://cdn.discourse.org/uploads/meta_discourse/1060/6496b3226de5168d.png","created_at":"2013-06-11T18:58:20-04:00","last_posted_at":"2013-06-11T21:48:17-04:00","bumped":true,"bumped_at":"2013-06-11T19:48:20-04:00","unseen":false,"title":"\"Topic_count\" instead of actual count","pinned":false,"visible":true,"closed":false,"archived":true,"views":28,"like_count":3,"has_best_of":false,"archetype":"regular","category_id":1,"posters":[{"extras":null,"description":"Original Poster","user_id":5293},{"extras":"latest","description":"Most Recent Poster","user_id":1}]},{"id":7389,"fancy_title":"I&rsquo;m trying to making linux container(lxc) vagrant box image","slug":"im-trying-to-making-linux-container-lxc-vagrant-box-image","posts_count":1,"reply_count":0,"highest_post_number":1,"image_url":"http://cdn.discourse.org/assets/emoji/wink.png","created_at":"2013-06-11T18:56:31-04:00","last_posted_at":"2013-06-11T18:56:31-04:00","bumped":true,"bumped_at":"2013-06-11T19:06:13-04:00","unseen":false,"title":"I'm trying to making linux container(lxc) vagrant box image","pinned":false,"visible":true,"closed":false,"archived":false,"views":25,"like_count":0,"has_best_of":false,"archetype":"regular","category_id":7,"posters":[{"extras":"latest","description":"Original Poster, Most Recent Poster","user_id":5425}]},{"id":7386,"fancy_title":"Mail settings shows password in clear text","slug":"mail-settings-shows-password-in-clear-text","posts_count":2,"reply_count":0,"highest_post_number":2,"image_url":null,"created_at":"2013-06-11T17:19:41-04:00","last_posted_at":"2013-06-11T19:05:33-04:00","bumped":true,"bumped_at":"2013-06-11T19:05:33-04:00","unseen":false,"title":"Mail settings shows password in clear text","pinned":false,"visible":true,"closed":false,"archived":false,"views":45,"like_count":5,"has_best_of":false,"archetype":"regular","category_id":1,"posters":[{"extras":null,"description":"Original Poster","user_id":1681},{"extras":"latest","description":"Most Recent Poster","user_id":247}]},{"id":7175,"fancy_title":"Relative time something was posted","slug":"relative-time-something-was-posted","posts_count":105,"reply_count":90,"highest_post_number":105,"image_url":"http://meta.discourse.org/uploads/meta_discourse/1007/0f5263b3ee0a0f45.png","created_at":"2013-06-04T19:05:09-04:00","last_posted_at":"2013-06-11T19:01:41-04:00","bumped":true,"bumped_at":"2013-06-11T19:01:41-04:00","unseen":false,"title":"Relative time something was posted","pinned":false,"visible":true,"closed":false,"archived":false,"views":433,"like_count":94,"has_best_of":true,"archetype":"regular","category_id":9,"posters":[{"extras":null,"description":"Original Poster","user_id":1374},{"extras":null,"description":"Most Posts","user_id":32},{"extras":null,"description":"Frequent Poster","user_id":406},{"extras":null,"description":"Frequent Poster","user_id":5438},{"extras":"latest","description":"Most Recent Poster","user_id":1263}]}]}}
diff --git a/test/javascripts/fixtures/site_settings.js b/test/javascripts/fixtures/site_settings.js
new file mode 100644
index 000000000..b6cb91076
--- /dev/null
+++ b/test/javascripts/fixtures/site_settings.js
@@ -0,0 +1,2 @@
+/*jshint maxlen:10000000 */
+Discourse.SiteSettings = {"title":"Discourse Meta","logo_url":"/assets/logo.png","logo_small_url":"/assets/logo-single.png","traditional_markdown_linebreaks":false,"top_menu":"latest|new|unread|read|favorited|categories","post_menu":"like|edit|flag|delete|share|bookmark|reply","share_links":"twitter|facebook|google+|email","track_external_right_clicks":false,"must_approve_users":false,"ga_tracking_code":"UA-33736483-2","ga_domain_name":"","enable_long_polling":true,"polling_interval":3000,"anon_polling_interval":30000,"min_post_length":20,"max_post_length":16000,"min_topic_title_length":15,"max_topic_title_length":255,"min_private_message_title_length":2,"allow_uncategorized_topics":true,"min_search_term_length":3,"flush_timings_secs":5,"supress_reply_directly_below":true,"email_domains_blacklist":"mailinator.com","email_domains_whitelist":null,"version_checks":true,"min_title_similar_length":10,"min_body_similar_length":15,"category_colors":"BF1E2E|F1592A|F7941D|9EB83B|3AB54A|12A89D|25AAE2|0E76BD|652D90|92278F|ED207B|8C6238|231F20|808281|B3B5B4|283890","max_upload_size_kb":1024,"category_featured_topics":6,"favicon_url":"/assets/favicon.ico","dynamic_favicon":false,"uncategorized_name":"uncategorized","uncategorized_color":"AB9364","uncategorized_text_color":"FFFFFF","invite_only":false,"login_required":false,"enable_local_logins":true,"enable_local_account_create":true,"enable_google_logins":true,"enable_yahoo_logins":true,"enable_twitter_logins":true,"enable_facebook_logins":true,"enable_cas_logins":false,"enable_github_logins":true,"enable_persona_logins":true,"educate_until_posts":2,"topic_views_heat_low":1000,"topic_views_heat_medium":2000,"topic_views_heat_high":5000};
\ No newline at end of file
diff --git a/test/javascripts/integration/header_test.js b/test/javascripts/integration/header_test.js
index dca99a727..d72d11631 100644
--- a/test/javascripts/integration/header_test.js
+++ b/test/javascripts/integration/header_test.js
@@ -1,11 +1,12 @@
+/*global module:true test:true ok:true visit:true expect:true exists:true count:true */
+
 module("Header", {
+
   setup: function() {
     Ember.run(Discourse, Discourse.advanceReadiness);
   },
 
   teardown: function() {
-    $('#discourse-modal').modal('hide')
-    $('#discourse-modal').remove()
     Discourse.reset();
   }
 });
diff --git a/test/javascripts/integration/list_topics_test.js b/test/javascripts/integration/list_topics_test.js
new file mode 100644
index 000000000..c31b4d2fb
--- /dev/null
+++ b/test/javascripts/integration/list_topics_test.js
@@ -0,0 +1,23 @@
+/*global module:true test:true ok:true visit:true expect:true exists:true count:true */
+
+module("List Topics", {
+  setup: function() {
+    Ember.run(Discourse, Discourse.advanceReadiness);
+  },
+
+  teardown: function() {
+    Discourse.reset();
+  }
+});
+
+test("/", function() {
+  expect(2);
+
+  visit("/").then(function() {
+    ok(exists("#topic-list"), "The list of topics was rendered");
+    ok(count('#topic-list .topic-list-item') > 0, "has topics");
+  });
+
+});
+
+
diff --git a/test/javascripts/test_helper.js b/test/javascripts/test_helper.js
index b318c3192..de1a6324a 100644
--- a/test/javascripts/test_helper.js
+++ b/test/javascripts/test_helper.js
@@ -1,3 +1,4 @@
+/*global count:true find:true document:true */
 
 //= require env
 
@@ -33,20 +34,26 @@
 //= require_tree .
 //= require_self
 
-document.write('<div id="ember-testing-container"><div id="ember-testing"></div></div>');
-document.write('<style>#ember-testing-container { position: absolute; background: white; bottom: 0; right: 0; width: 640px; height: 384px; overflow: auto; z-index: 9999; border: 1px solid #ccc; } #ember-testing { zoom: 50%; }</style>');
+//= require_tree ./fixtures
+
+// Trick JSHint into allow document.write
+var d = document;
+d.write('<div id="ember-testing-container"><div id="ember-testing"></div></div>');
+d.write('<style>#ember-testing-container { position: absolute; background: white; bottom: 0; right: 0; width: 640px; height: 384px; overflow: auto; z-index: 9999; border: 1px solid #ccc; } #ember-testing { zoom: 50%; }</style>');
 
 Discourse.rootElement = '#ember-testing';
 Discourse.setupForTesting();
 Discourse.injectTestHelpers();
 
 
-Discourse.SiteSettings = {"title":"Discourse Meta","logo_url":"/assets/logo.png","logo_small_url":"/assets/logo-single.png","traditional_markdown_linebreaks":false,"top_menu":"latest|new|unread|read|favorited|categories","post_menu":"like|edit|flag|delete|share|bookmark|reply","share_links":"twitter|facebook|google+|email","track_external_right_clicks":false,"must_approve_users":false,"ga_tracking_code":"UA-33736483-2","ga_domain_name":"","enable_long_polling":true,"polling_interval":3000,"anon_polling_interval":30000,"min_post_length":20,"max_post_length":16000,"min_topic_title_length":15,"max_topic_title_length":255,"min_private_message_title_length":2,"allow_uncategorized_topics":true,"min_search_term_length":3,"flush_timings_secs":5,"supress_reply_directly_below":true,"email_domains_blacklist":"mailinator.com","email_domains_whitelist":null,"version_checks":true,"min_title_similar_length":10,"min_body_similar_length":15,"category_colors":"BF1E2E|F1592A|F7941D|9EB83B|3AB54A|12A89D|25AAE2|0E76BD|652D90|92278F|ED207B|8C6238|231F20|808281|B3B5B4|283890","max_upload_size_kb":1024,"category_featured_topics":6,"favicon_url":"/assets/favicon.ico","dynamic_favicon":false,"uncategorized_name":"uncategorized","uncategorized_color":"AB9364","uncategorized_text_color":"FFFFFF","invite_only":false,"login_required":false,"enable_local_logins":true,"enable_local_account_create":true,"enable_google_logins":true,"enable_yahoo_logins":true,"enable_twitter_logins":true,"enable_facebook_logins":true,"enable_cas_logins":false,"enable_github_logins":true,"enable_persona_logins":true,"educate_until_posts":2,"topic_views_heat_low":1000,"topic_views_heat_medium":2000,"topic_views_heat_high":5000};
-
 Discourse.Router.map(function() {
   return Discourse.routeBuilder.call(this);
 });
 
 function exists(selector) {
-  return !!find(selector).length;
+  return !!count(selector);
+}
+
+function count(selector) {
+  return find(selector).length;
 }
\ No newline at end of file