Skip to content

Commit

Permalink
rack middleware to append mixpanel scripts
Browse files Browse the repository at this point in the history
  • Loading branch information
zevarito committed Jul 6, 2010
1 parent 3bae227 commit ce8c589
Show file tree
Hide file tree
Showing 6 changed files with 140 additions and 10 deletions.
1 change: 1 addition & 0 deletions lib/mixpanel.rb
@@ -1 +1,2 @@
require 'mixpanel/mixpanel'
require 'mixpanel/middleware'
61 changes: 61 additions & 0 deletions lib/mixpanel/middleware.rb
@@ -0,0 +1,61 @@
require 'rack'

class Middleware
def initialize(app, mixpanel_token)
@app = app
@token = mixpanel_token
end

def call(env)
status, headers, response = @app.call(env)

if is_html?(headers)
response = build_response(response)
headers = update_content_length(response, headers)
end

[status, headers, response]
end

def each(&block)
@response.each(&block)
end

private

def build_response(response)
body = ""

response.each do |part|
part.gsub!("</head>", "#{include_mixpanel_scripts}</head>")
body << part
end
end

def update_content_length(response, headers)
headers.merge("Content-Length" => response.join("").length.to_s)
end

def is_html?(headers)
headers["Content-Type"].include?("text/html") if headers.has_key?("Content-Type")
end

def include_mixpanel_scripts
<<-EOT
<script type='text/javascript'>
var mp_protocol = (('https:' == document.location.protocol) ? 'https://' : 'http://');
document.write(unescape('%3Cscript src="' + mp_protocol + 'api.mixpanel.com/site_media/js/api/mixpanel.js" type="text/javascript"%3E%3C/script%3E'));
</script>
<script type='text/javascript'>
try {
var mpmetrics = new MixpanelLib('#{@token}');
} catch(err) {
null_fn = function () {};
var mpmetrics = {
track: null_fn, track_funnel: null_fn, register: null_fn, register_once: null_fn, register_funnel: null_fn
};
}
</script>
EOT
end
end
16 changes: 6 additions & 10 deletions mixpanel.gemspec
@@ -1,3 +1,5 @@
files = ['README.rdoc', 'LICENSE', 'Rakefile', 'mixpanel.gemspec', '{spec,lib}/**/*'].map {|f| Dir[f]}.flatten

spec = Gem::Specification.new do |s|
s.name = "mixpanel"
s.version = "0.5.1"
Expand All @@ -8,20 +10,14 @@ spec = Gem::Specification.new do |s|
s.homepage = "http://cuboxsa.com"
s.platform = Gem::Platform::RUBY
s.summary = "Supports direct request api and javascript requests."
s.files = %w[
.gitignore
README.rdoc
LICENSE
Rakefile
mixpanel.gemspec
lib/mixpanel.rb
spec/spec_helper.rb
spec/mixpanel/mixpanel_spec.rb
]
s.files = files
s.require_path = "lib"
s.has_rdoc = false
s.extra_rdoc_files = ["README.rdoc"]
s.add_dependency 'json'
s.add_dependency 'rack'
s.add_development_dependency 'rspec'
s.add_development_dependency 'rack/test'
s.add_development_dependency 'fakeweb'
s.add_development_dependency 'nokogiri'
end
39 changes: 39 additions & 0 deletions spec/mixpanel/middleware_spec.rb
@@ -0,0 +1,39 @@
require 'spec_helper'

describe Middleware do
include Rack::Test::Methods

describe "Dummy apps, no text/html" do
before do
setup_rack_application(DummyApp)
get "/"
end

it "should pass through if the document is not text/html content type" do
last_response.body.should == DummyApp.new.body
end
end

describe "Appending mixpanel scripts" do
before do
setup_rack_application(HtmlApp)
get "/"
end

it "should append mixpanel scripts to head element" do
Nokogiri::HTML(last_response.body).search('head script').should_not be_empty
end

it "should use the specified token instantiating mixpanel lib" do
last_response.should =~ /new MixpanelLib\('#{MIX_PANEL_TOKEN}'\)/
end

it "should define Content-Length if not exist" do
last_response.headers.has_key?("Content-Length").should == true
end

it "should update Content-Length in headers" do
last_response.headers["Content-Length"].should_not == HtmlApp.new.body.length
end
end
end
3 changes: 3 additions & 0 deletions spec/spec_helper.rb
@@ -1,5 +1,8 @@
require File.join(File.dirname(__FILE__), "../lib", "mixpanel")
require 'rack/test'
require 'fakeweb'
require 'nokogiri'
Dir[File.expand_path(File.join(File.dirname(__FILE__),'support','**','*.rb'))].each {|f| require f}

MIX_PANEL_TOKEN = "e2d8b0bea559147844ffab3d607d26a6"

Expand Down
30 changes: 30 additions & 0 deletions spec/support/rack_apps.rb
@@ -0,0 +1,30 @@
def setup_rack_application(application)
stub!(:app).and_return(Middleware.new(application.new, MIX_PANEL_TOKEN))
end

class HtmlApp
def body
<<-EOT
<html>
<head>
</head>
<body>
</body>
</html>
EOT
end

def call(env)
["200", {"Content-Type" => "text/html"}, [body]]
end
end

class DummyApp
def body
""
end

def call(env)
["200", {}, [body]]
end
end

0 comments on commit ce8c589

Please sign in to comment.