<?xml version="1.0" encoding="UTF-8"?>
<commit>
  <added type="array"/>
  <modified type="array">
    <modified>
      <diff>@@ -68,8 +68,6 @@ Dir[File.join(File.dirname(__FILE__), 'campaign_monitor/*.rb')].each do |f|
 end
 
 class CampaignMonitor
-  include Helpers
-
   attr_reader :api_key, :api_url
   
   # Replace this API key with your own (http://www.campaignmonitor.com/api/)
@@ -92,7 +90,12 @@ class CampaignMonitor
   # Takes a CampaignMonitor API method name and set of parameters; returns the correct URL for the REST API.
   def request_url(method, params={})
     params.merge!('ApiKey' =&gt; api_key)
-    &quot;#{api_url}/#{method}?#{params.to_query}&quot;
+    
+    query = params.collect do |key, value|
+      &quot;#{CGI.escape(key.to_s)}=#{CGI.escape(value.to_s)}&quot;
+    end.sort * '&amp;'
+    
+    &quot;#{api_url}/#{method}?#{query}&quot;
   end
 
   # Does an HTTP GET on a given URL and returns the response body
@@ -171,6 +174,40 @@ class CampaignMonitor
   def add_subscriber(list_id, email, name)
     Result.new(Subscriber_Add(&quot;ListID&quot; =&gt; list_id, &quot;Email&quot; =&gt; email, &quot;Name&quot; =&gt; name))
   end
+  
+  
+  def handle_response(response)      
+    return [] if response.empty?
+
+    if response[&quot;Code&quot;].to_i == 0
+      # success!
+      yield(response)
+    else
+      # error!
+      raise response[&quot;Code&quot;] + &quot; - &quot; + response[&quot;Message&quot;]
+    end      
+  end
+
+  def wsdl_driver_factory
+    SOAP::WSDLDriverFactory.new(&quot;#{api_url}?WSDL&quot;)
+  end
+
+  def using_soap
+    driver = wsdl_driver_factory.create_rpc_driver
+    response = yield(driver)
+    driver.reset_stream
+  end
+
+  def timestamp_format
+    '%Y-%m-%d %H:%M:%S'
+  end
+
+  def formatted_timestamp(datetime, format=timestamp_format)
+    datetime.strftime(format)
+  end
+
+
+
 
   # Encapsulates
   class SubscriberBounce</diff>
      <filename>lib/campaign_monitor.rb</filename>
    </modified>
    <modified>
      <diff>@@ -1,8 +1,6 @@
 class CampaignMonitor
   # Provides access to the information about a campaign
   class Campaign
-    include Helpers
-    
     attr_reader :id, :subject, :sent_date, :total_recipients, :cm_client
 
     def initialize(id=nil, subject=nil, sent_date=nil, total_recipients=nil)</diff>
      <filename>lib/campaign_monitor/campaign.rb</filename>
    </modified>
    <modified>
      <diff>@@ -1,8 +1,6 @@
 class CampaignMonitor
   # Provides access to the lists and campaigns associated with a client
   class Client
-    include Helpers
-
     attr_reader :id, :name, :cm_client
 
     # Example</diff>
      <filename>lib/campaign_monitor/client.rb</filename>
    </modified>
    <modified>
      <diff>@@ -1,35 +1,17 @@
 class CampaignMonitor
   module Helpers
-    
-    def handle_response(response)      
-      return [] if response.empty?
-
-      if response[&quot;Code&quot;].to_i == 0
-        # success!
-        yield(response)
-      else
-        # error!
-        raise response[&quot;Code&quot;] + &quot; - &quot; + response[&quot;Message&quot;]
-      end      
-    end
-
-    def wsdl_driver_factory
-      SOAP::WSDLDriverFactory.new(&quot;#{api_url}?WSDL&quot;)
-    end
-
-    def using_soap
-      driver = wsdl_driver_factory.create_rpc_driver
-      response = yield(driver)
-      driver.reset_stream
-    end
-
-    def timestamp_format
-      '%Y-%m-%d %H:%M:%S'
+    def self.included(base)
+      base.class_eval do 
+        extend ClassMethods
+        include InstanceMethods
+      end
     end
 
-    def formatted_timestamp(datetime, format=timestamp_format)
-      datetime.strftime(format)
+    module ClassMethods
+    end  
+  
+    module InstanceMethods  
     end
-    
   end
+  
 end
\ No newline at end of file</diff>
      <filename>lib/campaign_monitor/helpers.rb</filename>
    </modified>
    <modified>
      <diff>@@ -4,8 +4,6 @@ class CampaignMonitor
   # Provides access to the subscribers and info about subscribers
   # associated with a Mailing List
   class List
-    include Helpers
-    
     attr_reader :id, :name, :cm_client
 
     # Example</diff>
      <filename>lib/campaign_monitor/list.rb</filename>
    </modified>
    <modified>
      <diff>@@ -1,8 +1,6 @@
 class CampaignMonitor
   # Provides the ability to add/remove subscribers from a list
   class Subscriber
-    include Helpers
-
     attr_accessor :email_address, :name, :date_subscribed
     attr_reader :cm_client
 </diff>
      <filename>lib/campaign_monitor/subscriber.rb</filename>
    </modified>
    <modified>
      <diff>@@ -1,12 +1,58 @@
+require 'rubygems'
+require 'campaign_monitor'
 require 'test/unit'
 
+CAMPAIGN_MONITOR_API_KEY  = 'Your API Key'
+CLIENT_NAME               = '_Test'
+LIST_NAME                 = '_List1'
+
 class CampaignMonitorTest &lt; Test::Unit::TestCase
   
-  def setup    
+  def setup
+    @cm = CampaignMonitor.new    
+  end
+  
+  def test_clients
+    clients = @cm.clients
+    assert clients.size &gt; 0
+    
+    assert_equal CLIENT_NAME, find_test_client(clients).name
   end
   
-  def test_truth
-    # TODO - Testify this gem
-    assert true
+  def test_lists
+    client = find_test_client
+    assert_not_nil client
+
+    lists = client.lists
+    assert lists.size &gt; 0
+    
+    list = find_test_list(lists)
+    assert_equal LIST_NAME, list.name
   end
+  
+  def test_list_add_subscriber
+    list = find_test_list
+
+    assert_success list.add_and_resubscribe('a@test.com', 'Test A')
+    assert_success list.remove_subscriber('a@test.com')
+  end
+  
+  def test_campaigns
+    client = find_test_client
+    assert_not_nil client.campaigns
+  end
+  
+  
+  protected
+    def assert_success(result)
+      assert result.succeeded?, result.message      
+    end
+    
+    def find_test_client(clients=@cm.clients)
+      clients.detect { |c| c.name == CLIENT_NAME }
+    end
+    
+    def find_test_list(lists=find_test_client.lists)
+      lists.detect { |l| l.name == LIST_NAME }
+    end
 end
\ No newline at end of file</diff>
      <filename>test/campaign_monitor_test.rb</filename>
    </modified>
  </modified>
  <removed type="array"/>
  <parents type="array">
    <parent>
      <id>88b0ec34f9d017def5c86dc3239dee292fb0933b</id>
    </parent>
  </parents>
  <author>
    <name>Jeremy Weiskotten</name>
    <email>jeremy.weiskotten@gmail.com</email>
  </author>
  <url>http://github.com/patientslikeme/campaign_monitor/commit/551349fec9b16efb7c2a4d496c0943720689c322</url>
  <id>551349fec9b16efb7c2a4d496c0943720689c322</id>
  <committed-date>2009-01-06T21:16:44-08:00</committed-date>
  <authored-date>2009-01-06T21:16:44-08:00</authored-date>
  <message>removed dependency on ActiveSupport, added a few basic unit tests</message>
  <tree>d1f626a770ea97460f22b42cce164db21946fa6b</tree>
  <committer>
    <name>Jeremy Weiskotten</name>
    <email>jeremy.weiskotten@gmail.com</email>
  </committer>
</commit>
