Skip to content
Browse files

Merge branch 'test_refactor'

  • Loading branch information...
2 parents 9e312b2 + 6f8d3fb commit 9d3983b35b9456f088f7c559ed9e56d338ceb79c @kyledrake kyledrake committed Apr 25, 2011
View
8 Gemfile
@@ -10,12 +10,13 @@ gem 'symboltable', '1.0.0'
gem 'dm-mysql-adapter', '1.1.0'
gem 'rack-fiber_pool', '0.9.1', :require => 'rack/fiber_pool'
gem 'rack-cache', '1.0.1', :require => 'rack/cache'
+gem 'em-http-request', '0.3.0'
gem 'thin'
-gem 'em-http-request', '1.0.0.beta.3'
gem 'em-synchrony', '0.2.0'
-gem 'rake', '0.8.7', :require => nil
+gem 'rake', '0.8.7', :require => nil
gem 'rmagick', '2.13.1', :require => 'RMagick'
gem 'rufus-scheduler', '2.0.8', :require => 'rufus/scheduler'
+gem 'async-rack', '0.5.1', :require => nil
group :development do
gem 'shotgun', '0.9', :require => nil
@@ -24,6 +25,7 @@ end
group :test do
gem 'rack-test', '0.5.7', :require => 'rack/test'
- gem 'contest', '0.1.2'
gem 'dm-sqlite-adapter', '1.1.0'
+ gem 'rspec', '2.5.0'
+ gem 'webmock', '1.6.2', :require => 'webmock/rspec'
end
View
37 Gemfile.lock
@@ -3,11 +3,14 @@ GEM
specs:
addressable (2.2.5)
archive-tar-minitar (0.5.2)
+ async-rack (0.5.1)
+ rack (~> 1.1)
columnize (0.3.2)
- contest (0.1.2)
- daemons (1.1.2)
+ crack (0.1.8)
+ daemons (1.1.3)
data_objects (0.10.3)
addressable (~> 2.1)
+ diff-lcs (1.1.2)
dm-core (1.1.0)
addressable (~> 2.2.4)
dm-do-adapter (1.1.0)
@@ -27,17 +30,14 @@ GEM
data_objects (= 0.10.3)
do_sqlite3 (0.10.3)
data_objects (= 0.10.3)
- em-http-request (1.0.0.beta.3)
- addressable (>= 2.2.3)
- em-socksify
- eventmachine
- http_parser.rb (>= 0.5.1)
- em-socksify (0.1.0)
- eventmachine
+ em-http-request (0.3.0)
+ addressable (>= 2.0.0)
+ escape_utils
+ eventmachine (>= 0.12.9)
em-synchrony (0.2.0)
eventmachine (>= 0.12.9)
+ escape_utils (0.2.3)
eventmachine (0.12.10)
- http_parser.rb (0.5.1)
linecache19 (0.5.12)
ruby_core_source (>= 0.1.4)
mime-types (1.16)
@@ -51,6 +51,14 @@ GEM
rest-client (1.6.1)
mime-types (>= 1.16)
rmagick (2.13.1)
+ rspec (2.5.0)
+ rspec-core (~> 2.5.0)
+ rspec-expectations (~> 2.5.0)
+ rspec-mocks (~> 2.5.0)
+ rspec-core (2.5.1)
+ rspec-expectations (2.5.0)
+ diff-lcs (~> 1.1.2)
+ rspec-mocks (2.5.0)
ruby-debug-base19 (0.11.25)
columnize (>= 0.3.1)
linecache19 (>= 0.5.11)
@@ -75,30 +83,35 @@ GEM
rack (>= 1.0.0)
tilt (1.2.2)
tzinfo (0.3.26)
+ webmock (1.6.2)
+ addressable (>= 2.2.2)
+ crack (>= 0.1.7)
yajl-ruby (0.8.2)
PLATFORMS
ruby
DEPENDENCIES
- contest (= 0.1.2)
+ async-rack (= 0.5.1)
dm-core (= 1.1.0)
dm-migrations (= 1.1.0)
dm-mysql-adapter (= 1.1.0)
dm-sqlite-adapter (= 1.1.0)
dm-timestamps (= 1.1.0)
- em-http-request (= 1.0.0.beta.3)
+ em-http-request (= 0.3.0)
em-synchrony (= 0.2.0)
rack-cache (= 1.0.1)
rack-fiber_pool (= 0.9.1)
rack-test (= 0.5.7)
rake (= 0.8.7)
rest-client (= 1.6.1)
rmagick (= 2.13.1)
+ rspec (= 2.5.0)
ruby-debug19 (= 0.11.6)
rufus-scheduler (= 2.0.8)
shotgun (= 0.9)
sinatra (= 1.2.1)
symboltable (= 1.0.0)
thin
+ webmock (= 1.6.2)
yajl-ruby (= 0.8.2)
View
1 config.ru
@@ -1,2 +1,3 @@
require File.join('.', 'environment.rb')
+use Rack::FiberPool
run PdxPacman
View
2 environment.rb
@@ -3,10 +3,10 @@
require "bundler"
Bundler.setup
Bundler.require
+require 'async-rack'
class Sinatra::Base
configure do
- use Rack::FiberPool
use Rack::Cache, :verbose => false,
:metastore => "file:cache/meta",
:entitystore => "file:cache/body"
View
15 models/game.rb
@@ -8,7 +8,20 @@ class Game
has n, :teams
has n, :player
- def pick_team()
+ after :create do
+ ['red', 'blue'].each {|color| teams.create :name => color}
+ end
+
+ def self.create_unless_exists(layer_id)
+ game = first :layer_id => layer_id
+ unless game
+ response = Geoloqi.get Geoloqi::OAUTH_TOKEN, 'layer/info/' + layer_id
+ game = create :layer_id => layer_id, :name => response.name
+ end
+ game
+ end
+
+ def pick_team
# At this point we can be sure there are already 2 teams in the game since the game
# was created in the "/games/:layer_id/join"
if teams[0].players.count < teams[1].players.count
View
61 models/geoloqi.rb
@@ -2,6 +2,13 @@
RestClient.log = STDOUT
module Geoloqi
+ class Error < StandardError
+ def initialize(type, message=nil)
+ type += " - #{message}" if message
+ super type
+ end
+ end
+
API_URL = 'https://api.geoloqi.com/1/'
def self.headers(oauth_token)
{'Authorization' => "OAuth #{oauth_token}", 'Content-Type' => 'application/json'}
@@ -10,57 +17,31 @@ def self.headers(oauth_token)
def self.run(meth, oauth_token, url, body=nil)
args = {:head => headers(oauth_token)}
args[:body] = body.to_json if body
- begin
- puts "ARGS: #{args[:body].inspect}\nURL:#{API_URL+url}" unless url =~ /place\/list/ || url =~ /share\/last/
- rescue
- puts "ERROR!"
- end
response = JSON.parse EM::Synchrony.sync(EventMachine::HttpRequest.new(API_URL+url).send(meth.to_sym, args)).response
- begin
- puts "RESPONSE: #{response.inspect}" unless url =~ /place\/list/ || url =~ /share\/last/
- rescue
- puts "ERROR!"
+ raise Error.new(response['error'], response['error_description']) if response['error']
+
+ case response
+ when Array
+ response.map! {|e| SymbolTable.new e}
+ when Hash
+ SymbolTable.new response
end
- response
end
def self.post(oauth_token, url, body)
- obj = run :post, oauth_token, url, body
- case obj
- when Array
- ret = []
- obj.each do |el|
- ret << SymbolTable.new(el)
- end
- when Hash
- ret = SymbolTable.new obj
- end
- ret
+ run :post, oauth_token, url, body
end
def self.get(oauth_token, url)
- obj = run :get, oauth_token, url
- case obj
- when Array
- ret = []
- obj.each do |el|
- ret << SymbolTable.new(el)
- end
- when Hash
- ret = SymbolTable.new obj
- end
- ret
+ run :get, oauth_token, url
end
def self.get_token(auth_code, redirect_uri)
- args = {} # {:head => {'Authorization' => "Basic " + Base64.encode64(Geoloqi::CLIENT_ID + ":" + Geoloqi::CLIENT_SECRET)}}
- args[:body] = {
- client_id: Geoloqi::CLIENT_ID,
- client_secret: Geoloqi::CLIENT_SECRET,
- code: auth_code,
- grant_type: "authorization_code",
- redirect_uri: redirect_uri
- }
+ args = {:body => Rack::Utils.escape(:client_id => Geoloqi::CLIENT_ID,
+ :client_secret => Geoloqi::CLIENT_SECRET,
+ :code => auth_code,
+ :grant_type => "authorization_code",
+ :redirect_uri => redirect_uri)}
JSON.parse EM::Synchrony.sync(EventMachine::HttpRequest.new(API_URL+"oauth/token").post(args)).response
end
end
View
60 pdx_pacman.rb
@@ -5,52 +5,40 @@ class PdxPacman < Sinatra::Base
end
get '/game/:layer_id/join' do
- oauth_token = Geoloqi.get_token(params[:code], Geoloqi::BASE_URI + "game/" + params[:layer_id] + "/join")["access_token"]
- @game = Game.first :layer_id => params[:layer_id]
- if @game == nil
- response = Geoloqi.get Geoloqi::OAUTH_TOKEN, 'layer/info/' + params[:layer_id]
- @game = Game.create :layer_id => params[:layer_id], :name => response.name
- @game.teams.create :name => "red"
- @game.teams.create :name => "blue"
- end
- @oauth_token = oauth_token
- response = Geoloqi.get @oauth_token, 'layer/info/' + params[:layer_id]
+ @oauth_token = Geoloqi.get_token(params[:code], Geoloqi::BASE_URI+'game/'+params[:layer_id]+'/join')['access_token']
+ @game = Game.create_unless_exists params[:layer_id]
+ response = Geoloqi.get @oauth_token, 'layer/info/'+params[:layer_id]
user_profile = Geoloqi.get @oauth_token, 'account/profile'
@player = Player.first :geoloqi_user_id => user_profile.user_id, :game => @game
- if response.subscription.nil? || response.subscription == false || @player == nil
- # The player has never subscribed to the layer before, so create a new record in our DB and set up their shared tokens.
-
- # generate shared token so we can retrieve their location for the map later
+ if response.subscription.nil? || response.subscription == false || @player.nil?
+ # The player has never subscribed to the layer before, so create a new record in our DB and set up their shared tokens.
+ # Generate shared token so we can retrieve their location for the map later
shared_token = Geoloqi.post @oauth_token, 'link/create', {:description => "Created for "+@game.name, :minutes => 240}
- # subscribe the player to the layer
+ # Subscribe the player to the layer
Geoloqi.get @oauth_token, 'layer/subscribe/' + params[:layer_id]
- if @player == nil
- @player = Player.new
- # If user_profile.profile_image is not there or is null, don't do this (Should prevent errors on non-twitter accounts)
- @player.profile_image = user_profile.profile_image unless user_profile.profile_image.nil? || user_profile.profile_image.empty?
- @player.name = user_profile.username
- @player.geoloqi_user_id = user_profile.user_id
- @player.token = shared_token.token
- @player.game = @game
- # assign the player to a team
- # TODO: store the team in the layer subscription?
- # layer/subscription/:layer_id :body => {:settings => {:team_id => @team.id}}
- @player.team = @game.pick_team
- @player.save
- end
-
- # send message to user indicating team
- @player.send_message("You're on the " + @player.team.name + " team!").to_json
-
- redirect "/game/" + params[:layer_id]
- else
- redirect "/game/" + params[:layer_id]
+ if @player.nil?
+ @player = Player.new
+ # If user_profile.profile_image is not there or is null, don't do this (Should prevent errors on non-twitter accounts)
+ @player.profile_image = user_profile.profile_image unless user_profile.profile_image.nil? || user_profile.profile_image.empty?
+ @player.name = user_profile.username
+ @player.geoloqi_user_id = user_profile.user_id
+ @player.token = shared_token.token
+ @player.game = @game
+ # assign the player to a team
+ # TODO: store the team in the layer subscription?
+ # layer/subscription/:layer_id :body => {:settings => {:team_id => @team.id}}
+ @player.team = @game.pick_team
+ @player.save
+ end
+ # send message to user indicating team
+ @player.send_message("You're on the " + @player.team.name + " team!").to_json
end
+ redirect "/game/" + params[:layer_id]
end
get '/game/:layer_id/mobile' do
View
92 spec/pdx_pacman.rb
@@ -0,0 +1,92 @@
+require File.dirname(__FILE__) + '/spec_helper'
+
+describe PdxPacman do
+ include WebMock::API
+ include Rack::Test::Methods
+
+ def app
+ PdxPacman
+ end
+
+ it 'returns join page, create game, and add teams for valid layer' do
+ EM.synchrony do
+=begin
+ stub_request(:post, "https://api.geoloqi.com/1/oauth/token").with(:body => {:client_id=>"client_id1234",
+ :client_secret=>"client_secret1234",
+ :code=>"1234",
+ :grant_type=>"authorization_code",
+ :redirect_uri=>"http://mapattack.org/game/1QY/join"}).to_return('lol')
+=end
+
+ stub_request(:post, "https://api.geoloqi.com/1/oauth/token").
+ with(:body => Rack::Utils.escape(:client_id => "client_id1234",
+ :client_secret => "client_secret1234",
+ :code => "1234",
+ :grant_type => "authorization_code",
+ :redirect_uri => "http://mapattack.org/game/1QY/join")).
+ to_return(:status => 200,
+ :headers => {:content_type => 'application/json'},
+ :body => {:access_token => 'access_token1234',
+ :scope => nil,
+ :expires_in => '86400',
+ :refresh_token => 'refresh_token1234'}.to_json)
+
+ stub_request(:get, "https://api.geoloqi.com/1/layer/info/1QY").
+ with(:body => '').
+ to_return(:status => 200,
+ :headers => {},
+ :body => {:layer_id => '1QY',
+ :type => 'normal',
+ :name => 'name',
+ :description => 'description',
+ :icon => 'http://localhost/test.png',
+ :public => '1',
+ :url => 'https://a.geoloqi.com/oauth/authorize?response_type=code&client_id=7bcd478f26bd14b1fed18e9fe59e506f&redirect_uri=http%3A%2F%2Fmapattack.org%2Fgame%2F1Lx%2Fjoin',
+ :subscription => {'subscribed' => '0', 'date_subscribed' => '2011-01-01 01:01:01'},
+ :settings => []}.to_json)
+
+ stub_request(:get, "https://api.geoloqi.com/1/account/profile").
+ with(:body => '',
+ :headers => {:authorization => 'OAuth access_token1234', :content_type => 'application/json'}).
+ to_return(:status => 200,
+ :body => {:user_id => 'user_id1234', :email => 'e@mail.com1234', :profile_image => 'http://localhost/test.png'}.to_json)
+
+ stub_request(:post, "https://api.geoloqi.com/1/link/create").
+ with(:body => {:description => 'Created for name', :minutes => 240}.to_json,
+ :headers => {'Authorization'=>'OAuth access_token1234', 'Content-Type'=>'application/json'}).
+ to_return(:status => 200, :body => {:link => 'http://geoloqi.com/name/token12',
+ :shortlink => 'http://loqi.me/token12',
+ :token => 'token12'}.to_json)
+
+ stub_request(:get, "https://api.geoloqi.com/1/layer/subscribe/1QY").
+ with(:headers => {'Authorization'=>'OAuth access_token1234', 'Content-Type'=>'application/json'}).
+ to_return(:status => 200, :body => {:layer_id => '1QY',:subscribed => 1}.to_json)
+
+ stub_request(:post, "https://api.geoloqi.com/1/message/send").
+ with(:body => {:user_id => 'user_id1234', :text => "You're on the blue team!"}.to_json,
+ :headers => {:authorization => 'OAuth oauth1234', :content_type => 'application/json'}).
+ to_return(:status => 200, :body => {:result => 'ok', :username => 'username1234', :user_id => 'user_id1234'}.to_json)
+
+ get '/game/1QY/join?code=1234'
+ EventMachine.stop
+ end
+ last_response.should be_redirect
+ last_response.headers['Location'].should == 'http://example.org/game/1QY'
+ Game.count.should == 1
+ Game.first.layer_id.should == '1QY'
+ Team.count.should == 2
+ Team.all(:game => Game.first).length.should == 2
+ Team.all(:name => 'red').length.should == 1
+ Team.all(:name => 'blue').length.should == 1
+ end
+=begin
+ it 'joins a player to the game' do
+ EM.synchrony do
+ post '/game/1QY/join.json', :oauth_token => 'xwiwcvu'
+ #, :content_type => 'application/json'
+ EventMachine.stop
+ end
+ last_response.should be_ok
+ end
+=end
+end
View
7 spec/spec_helper.rb
@@ -0,0 +1,7 @@
+ENV['RACK_ENV'] = 'test'
+raise 'Forget it.' if ENV['RACK_ENV'] == 'production'
+require File.join(File.expand_path(File.dirname(__FILE__)), '..', 'environment.rb')
+require File.dirname(__FILE__) + '/spec_helper'
+require 'eventmachine'
+Bundler.require :test
+DataMapper.auto_migrate!
View
31 test/test.rb
@@ -1,31 +0,0 @@
-ENV['RACK_ENV'] = 'test'
-raise 'Forget it.' if ENV['RACK_ENV'] == 'production'
-
-require File.join(File.expand_path(File.dirname(__FILE__)), '..', 'environment.rb')
-require 'test/unit'
-require 'eventmachine'
-Bundler.require :test
-DataMapper.auto_migrate!
-
-class Test::Unit::TestCase
- include Rack::Test::Methods
- def mock_app(base=Sinatra::Base, &block)
- @app = Sinatra.new base, &block
- end
- def app; @app end
- def app=(new_app); @app = new_app end
-end
-
-class ControllerTests < Test::Unit::TestCase
- def app
- PdxPacman
- end
-
- context "a game" do
- test "loads the join page" do
- get 'game/test/join'
- assert last_response.ok?
- assert last_response.body =~ /Join Game/
- end
- end
-end
View
BIN vendor/cache/contest-0.1.2.gem
Binary file not shown.
View
BIN vendor/cache/daemons-1.1.2.gem
Binary file not shown.
View
BIN vendor/cache/em-http-request-1.0.0.beta.3.gem
Binary file not shown.
View
BIN vendor/cache/em-socksify-0.1.0.gem
Binary file not shown.
View
BIN vendor/cache/http_parser.rb-0.5.1.gem
Binary file not shown.
View
57 views/join.erb
@@ -1,57 +0,0 @@
-<html>
-<head>
- <title>PacMap</title>
- <style type="text/css">
- body {
- padding: 0;
- margin: 0;
- font: 12pt Helvetica, sans-serif;
- color: #222;
- text-shadow: #ddd 0 1px;
- background: #ccc;
- }
- a img {
- border: 0;
- }
- .game-title {
- font-size: 15pt;
- font-weight: bold;
- text-align: center;
- }
- </style>
- <meta name="viewport" content="initial-scale=1.0">
- <link rel="stylesheet" type="text/css" href="/button.css" />
- <script src="http://code.jquery.com/jquery-1.4.2.min.js"></script>
- <script type="text/javascript">
- $(function(){
- $("#join-btn").click(function(){
- $("#join-btn").hide();
- $("#join-btn-loader").show();
-
- $.post("/game/"+$("#layer_id").val()+"/join.json", {
- oauth_token: $("#oauth_token").val()
- }, function(data){
- window.location = "/game/"+$("#layer_id").val();
- }, "json");
- });
- });
- </script>
-</head>
-<body>
-
-<div style="padding: 8px;">
-
- <div style="padding: 8px; margin-bottom: 15px;">
- Real-time Geolocation game for iPhone and Android! Collect the most coins to win!
- </div>
-
- <div style="text-align: center;">
- <input type="button" class="btn btn-ok" value="Join Game" id="join-btn" />
- <div style="display: none;" id="join-btn-loader"><img src="/img/wakawaka.gif" width="24" height="24" /></div>
- <input type="hidden" id="layer_id" value="<%= @game.layer_id %>" />
- <input type="hidden" id="oauth_token" value="<%= @oauth_token %>" />
- </div>
-</div>
-
-</body>
-</html>

0 comments on commit 9d3983b

Please sign in to comment.
Something went wrong with that request. Please try again.