Part of Dev Bootcamp's thick client challenge for the 2014 Chorus Frogs.
- Build a client side heavy Rails application.
- Consume a JSON API.
- Build Single Page App.
- write organized JavaScript code
Your mission: build a one-page app using Javascript to render a simple dashboard for a twitter application. The HTML, CSS, and back-end are already written for you -- all you need to do is write the JavaScript.
requires ruby and rubygems.
$ bundle install
$ rake db:create && rake db:migrate && rake db:seed
$ rails server
to run the tests:
$ rake db:test:prepare
$ rake spec
$ brew install phantomjs
$ RAILS_ENV=test bundle exec rake spec:javascript
Your site needs to have the following functionality:
On page load, the 50 most recent tweets are displayed in the 'river' running down the middle of the page.
On page load, the 10 most popular hashtags are displayed.
A user can create a tweet, which will get saved into the database with a fake username, fake handle, and fake avatar (which is all handled server-side).
Any hashtags the tweet includes (e.g. #yolo), should also be associated with that tweet.
The new tweet should appear atop the 'river', preferrably with some sort of animation.
A user can search for a specific hashtag using the search bar. The results of the search will be displayed in the river, replacing whatever was there before.
If the user searches for a hashtag that does not exist, the search bar turns red.
A user can click on a trending topic in the trends box, which causes the river to display all tweets that are associated with that hashtag, replacing whatever was there before.
When a user clicks on the Lil Twitter header, the 50 most recent tweets are displayed.
All of this will be accomplished using JavaScript. Spend some time thinking about your architecture – what objects do you need? What are their interfaces? What does your file structure look like? Make sure you aren't micromanaging or over-designing -- Big Design Up Front is never great -- but your team will benefit from some basic architecture desicisions before starting.
Okay, now build the thing. You should avoid any changes to the server-side code, although if you feel like changes are necessary, implement them and make sure the tests reflect your alterations. You will need to remove the filler elements in app/views/index.html
. Structural changes to HTML and CSS should not be necessary, and it is generally a bad idea to unilaterally change a resource that your entire team depends on. Any changes to the existing code base, no matter how small, should be done intentionally and in consultation with your entire team.
JavaScript can be more difficult to test than ruby code, and OO design is often used as a replacement for full test coverage. That said, you should still be writing tests for your JavaScript code base. We've already installed the jasmine-rails gem for you. Some guidelines:
- testing your view objects and DOM interaction is difficult, as it requires a fair amount of setup to get right. It is more important that you test the cyclomatic complexity of your controllers and models.
- AJAX calls are also hard to test, and should be stubbed out for the purposes of your test suite. Use Jasmine spies to test that these functions have been called.
- Your integration testing should be handled through capybara. You can use the Poltergeist driver for feature testing with a focus on JavaScript functionality.
The benefits of OO architecture is that it is easily extendable. Add an additional feture to your application, like:
- a system for checking if new tweets have been created since page load, using long-polling.
- have the river of tweets only display 10 tweets, and dynamically load more when the user scrolls to the bottom of the page.
- give the user the ability to click hashtags inside tweets, which would display tweets associated with that hashtag.
GET /tweets/recent
returns the 50 most recently created tweets in JSON format. The response body looks like this:
[
{ "avatar_url":"http://robohash.org/marco_schumm",
"content":"Ut fugit ut labore repellendus.",
"created_at":"2014-07-20T20:27:42Z",
"handle":"@marco_schumm",
"id":500,
"updated_at":"2014-07-20T20:27:42Z",
"username":"Adaline Bins",
"hashtag_names": [ "est", "rerum", "distinctio" ] }
]
GET /tweets/search/:hashtag
returns the 50 most recent tweets associated with the given hashtag, with a format similar to the /recent
endpoint. Will return an empty body with a status code of 404 if the hastag does not exist.
POST /tweets
creates a new a tweet and associates it with the specified hashtags, if provided. Hashtags that did not previously exist are also created. a request body should take this format:
"tweet":
{ "avatar_url":"http://robohash.org/marco_schumm",
"content":"Ut fugit ut labore repellendus.",
"handle":"@marco_schumm",
"username":"Adaline Bins" }
hashtags: [ 'foo', 'bar', 'baz' ]
If no data is provided for avatar_url, content, handle, or username, fake data is used instead.
The endpoint returns the created tweet as JSON.
{ "avatar_url":"http://robohash.org/marco_schumm",
"content":"Ut fugit ut labore repellendus.",
"created_at":"2014-07-20T20:27:42Z",
"handle":"@marco_schumm",
"id":500,
"updated_at":"2014-07-20T20:27:42Z",
"username":"Adaline Bins",
"hashtag_names": [ "est", "rerum", "distinctio" ] }
GET /hashtags/popular
returns the names of the 10 most popular hashtags. The output looks like this:
[ "est",
"voluptas",
"consequatur",
"at",
"accusamus",
"doloremque",
"culpa",
"quod",
"iure",
"sint" ]