gregfitz23-RegPath 0.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
data/History.txt ADDED
@@ -0,0 +1,6 @@
1
+ === 1.0.0 / 2008-12-17
2
+
3
+ * 1 major enhancement
4
+
5
+ * Birthday!
6
+
data/Manifest.txt ADDED
@@ -0,0 +1,28 @@
1
+ History.txt
2
+ Manifest.txt
3
+ README.txt
4
+ Rakefile
5
+ bin/reg_path
6
+ lib/reg_path.rb
7
+ lib/reg_path/_progress_bar.html.erb
8
+ lib/reg_path/helpers/reg_path_helper.rb
9
+ lib/reg_path/mailer/reg_path_mailer.rb
10
+ lib/reg_path/mailer/reg_path_mailer/house_form.html.erb
11
+ lib/reg_path/offer_engine/models/offer.rb
12
+ lib/reg_path/offer_engine/models/reg_path.rb
13
+ lib/reg_path/offer_engine/models/submission.rb
14
+ lib/reg_path/offer_engine/models/user.rb
15
+ lib/reg_path/offer_engine/client.rb
16
+ lib/reg_path/properties.rb
17
+ lib/reg_path/reg_path.rb
18
+ test/test_reg_path.rb
19
+ test/confirmation_page.html.erb
20
+ test/empty_offers.xml
21
+ test/long_form.html.erb
22
+ test/test_offer_engine_client.rb
23
+ test/offers.xml
24
+ test/reg_path.xml
25
+ test/test_reg_path.rb
26
+ test/short_form.html.erb
27
+ test/submission.xml
28
+ test/submission_no_conf.xml
data/README ADDED
File without changes
data/README.txt ADDED
@@ -0,0 +1,48 @@
1
+ = RegPath
2
+
3
+ * FIX (url)
4
+
5
+ == DESCRIPTION:
6
+
7
+ FIX (describe your package)
8
+
9
+ == FEATURES/PROBLEMS:
10
+
11
+ * FIX (list of features or problems)
12
+
13
+ == SYNOPSIS:
14
+
15
+ FIX (code sample of usage)
16
+
17
+ == REQUIREMENTS:
18
+
19
+ * FIX (list of requirements)
20
+
21
+ == INSTALL:
22
+
23
+ * FIX (sudo gem install, anything else)
24
+
25
+ == LICENSE:
26
+
27
+ (The MIT License)
28
+
29
+ Copyright (c) 2008 FIX
30
+
31
+ Permission is hereby granted, free of charge, to any person obtaining
32
+ a copy of this software and associated documentation files (the
33
+ 'Software'), to deal in the Software without restriction, including
34
+ without limitation the rights to use, copy, modify, merge, publish,
35
+ distribute, sublicense, and/or sell copies of the Software, and to
36
+ permit persons to whom the Software is furnished to do so, subject to
37
+ the following conditions:
38
+
39
+ The above copyright notice and this permission notice shall be
40
+ included in all copies or substantial portions of the Software.
41
+
42
+ THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND,
43
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
44
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
45
+ IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
46
+ CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
47
+ TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
48
+ SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/RegPath.gemspec ADDED
@@ -0,0 +1,32 @@
1
+ # -*- encoding: utf-8 -*-
2
+
3
+ Gem::Specification.new do |s|
4
+ s.name = %q{RegPath}
5
+ s.version = "0.0.1"
6
+
7
+ s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
8
+ s.authors = ["Greg Fitzgerald"]
9
+ s.date = %q{2009-04-26}
10
+ s.default_executable = %q{reg_path}
11
+ s.description = %q{TODO}
12
+ s.email = %q{greg_fitz@yahoo.com}
13
+ s.executables = ["reg_path"]
14
+ s.extra_rdoc_files = ["README", "README.txt"]
15
+ s.files = ["History.txt", "Manifest.txt", "README.txt", "RegPath.gemspec", "VERSION.yml", "bin/reg_path", "lib/reg_path", "lib/reg_path/_progress_bar.html.erb", "lib/reg_path/helpers", "lib/reg_path/helpers/reg_path_helper.rb", "lib/reg_path/mailer", "lib/reg_path/mailer/reg_path_mailer", "lib/reg_path/mailer/reg_path_mailer/house_form.html.erb", "lib/reg_path/mailer/reg_path_mailer.rb", "lib/reg_path/models", "lib/reg_path/offer_engine", "lib/reg_path/offer_engine/client.rb", "lib/reg_path/offer_engine/models", "lib/reg_path/offer_engine/models/offer.rb", "lib/reg_path/offer_engine/models/reg_path.rb", "lib/reg_path/offer_engine/models/submission.rb", "lib/reg_path/offer_engine/models/user.rb", "lib/reg_path/properties.rb", "lib/reg_path/reg_path.rb", "lib/reg_path.rb", "test/confirmation_page.html.erb", "test/empty_offers.xml", "test/house_form.html.erb", "test/long_form.html.erb", "test/offers.xml", "test/reg_path.xml", "test/routes.rb", "test/short_form.html.erb", "test/submission.xml", "test/submission_no_conf.xml", "test/test_helper.rb", "test/test_offer_engine_client.rb", "test/test_reg_path.rb", "README"]
16
+ s.has_rdoc = true
17
+ s.homepage = %q{}
18
+ s.rdoc_options = ["--inline-source", "--charset=UTF-8"]
19
+ s.require_paths = ["lib"]
20
+ s.rubygems_version = %q{1.3.1}
21
+ s.summary = %q{TODO}
22
+
23
+ if s.respond_to? :specification_version then
24
+ current_version = Gem::Specification::CURRENT_SPECIFICATION_VERSION
25
+ s.specification_version = 2
26
+
27
+ if Gem::Version.new(Gem::RubyGemsVersion) >= Gem::Version.new('1.2.0') then
28
+ else
29
+ end
30
+ else
31
+ end
32
+ end
data/VERSION.yml ADDED
@@ -0,0 +1,4 @@
1
+ ---
2
+ :major: 0
3
+ :minor: 0
4
+ :patch: 1
data/bin/reg_path ADDED
File without changes
data/lib/reg_path.rb ADDED
@@ -0,0 +1,16 @@
1
+ class RegPath
2
+ VERSION='1.0.3'
3
+ end
4
+
5
+ require "action_mailer"
6
+ require "active_resource"
7
+ require "action_controller"
8
+ require "active_support"
9
+ require_dependency File.join(File.dirname(__FILE__), "reg_path/properties")
10
+ #
11
+ require_dependency File.join(File.dirname(__FILE__), "reg_path/offer_engine/client")
12
+ require_dependency File.join(File.dirname(__FILE__), "reg_path/offer_engine/models/submission")
13
+ require_dependency File.join(File.dirname(__FILE__), "reg_path/offer_engine/models/reg_path")
14
+ require_dependency File.join(File.dirname(__FILE__), "reg_path/offer_engine/models/offer")
15
+ require_dependency File.join(File.dirname(__FILE__), "reg_path/offer_engine/models/user")
16
+ require_dependency File.join(File.dirname(__FILE__), "reg_path/reg_path")
@@ -0,0 +1,17 @@
1
+ <div class="progress-bar">
2
+ <div class="finish">Finish</div>
3
+ <div class="start">Start</div>
4
+ <div style="clear:both"></div>
5
+ <table cellspacing='1' cellpadding='0'>
6
+ <tr class="bar">
7
+ <% (0..num_steps).each do |i| %>
8
+ <%
9
+ klass = []
10
+ klass << 'green' if i <= step
11
+ klass << 'last' if i == num_steps - 1
12
+ %>
13
+ <td class="<%= klass.join(" ") %>">&nbsp;</td>
14
+ <% end %>
15
+ </tr>
16
+ </table>
17
+ </div>
@@ -0,0 +1,21 @@
1
+ module RegPathHelper
2
+
3
+ def progress_bar(step, num_steps)
4
+ render(:partial => 'common/progress_bar', :locals=>{:num_steps=>num_steps, :step=>step}) if num_steps && step
5
+ end
6
+
7
+ def participation_header(options={})
8
+ name = ""
9
+ name << ", #{options[:name]}" if options[:name]
10
+
11
+ thank_you_text = options[:thank_you_text] || "Thank you"
12
+ participation_text = options[:participation_text] || "Thank you for participating"
13
+
14
+ terminator = options[:terminator] || "!"
15
+ (request.post? ? participation_text : thank_you_text) << name << terminator
16
+ end
17
+
18
+ def skip_this_link
19
+ link_to 'Skip this', :action=>:offers
20
+ end
21
+ end
@@ -0,0 +1,30 @@
1
+ require "open-uri"
2
+ class RegPathMailer < ActionMailer::Base
3
+
4
+ def house_form(params)
5
+ standard_mail(params)
6
+ end
7
+
8
+ def foodfit(params)
9
+ standard_mail(params)
10
+ end
11
+
12
+ private
13
+ def standard_mail(params)
14
+ template_root = overridden_template_or_default
15
+ recipients params[:to]
16
+ from params.delete(:from)
17
+ subject params.delete(:subject) || "Thank you for your interest in our offers."
18
+ content_type "text/html"
19
+
20
+ body params
21
+ end
22
+
23
+ def overridden_template_or_default
24
+ if File.exists?(File.join(template_root || "", "reg_path_mailer/#{@template}.html.erb"))
25
+ template_root
26
+ else
27
+ File.dirname(__FILE__)
28
+ end
29
+ end
30
+ end
@@ -0,0 +1,48 @@
1
+ require "open-uri"
2
+ # require File.join(File.dirname(__FILE__), "offer_engine/models/submission")
3
+ =begin
4
+ The *OfferEngineClient* class provides an interface for connecting to the OfferEngine.
5
+ It exposes two main methods, get_next_offers and submit_to_offer_engine which are resposible for requesting and sending data to/from the server.
6
+ =end
7
+ module OfferEngine
8
+ class Client
9
+
10
+ #Submit the passed in params to the OfferEngine.
11
+ #If this class, or any extending classes, provide a handler method for the particular offer type being sent back to the OfferEngine, call that.
12
+ #Otherwise, use the standard submit method.
13
+ def submit_to_offer_engine(params)
14
+ offer_type = params.delete(:reg_path_offer_type)
15
+ if offer_type && self.respond_to?("_#{offer_type}_submit_to_offer_engine")
16
+ submission_xml = self.__send__("_#{offer_type}_submit_to_offer_engine", params) #handle non-standard forms (e.g. multiple offers on short form)
17
+ else
18
+ submission_xml = _submit_to_offer_engine(params)
19
+ end
20
+ OfferEngine::Models::Submission.new.load(Hash.from_xml(submission_xml)["submission"]) unless submission_xml.blank?
21
+ end
22
+
23
+ def add_data(email, keys, values, options={})
24
+ uri = URI.parse("#{OfferEngine::Properties.offer_engine_host}/data_store/add_data?email=#{email}&#{keys.to_query('keys')}&#{values.to_query('values')}&#{options.to_query}&#{OfferEngine::Properties.source.to_query(:source)}")
25
+ resp = Net::HTTP.get(uri)
26
+ return resp.is_a?(Net::HTTPSuccess)
27
+ end
28
+
29
+ protected
30
+ #short form offers will all be in the params at once, so we need to parse before submitting
31
+ def _short_form_submit_to_offer_engine(params)
32
+ submission_xml = ""
33
+ params.keys.each do |p|
34
+ submission_xml = _submit_to_offer_engine({:offer_id => /[0-9]+/.match(p)[0], params[p] => "true", :email => params[:email]}) if /^offer_[0-9]+$/.match(p)
35
+ end
36
+ submission_xml
37
+ end
38
+
39
+ private
40
+ def _submit_to_offer_engine(params)
41
+ url = URI.parse(OfferEngine::Properties.offer_engine_submit_offer_path)
42
+ params[:source] = OfferEngine::Properties.source
43
+ response = Net::HTTP.new(url.host, url.port).start {|http| http.post(url.path, params.to_query) }
44
+
45
+ response.body
46
+ end
47
+ end
48
+ end
@@ -0,0 +1,7 @@
1
+ module OfferEngine
2
+ module Models
3
+ class Offer < ActiveResource::Base
4
+ self.site = OfferEngine::Properties.offer_engine_host
5
+ end
6
+ end
7
+ end
@@ -0,0 +1,12 @@
1
+ module OfferEngine
2
+ module Models
3
+ class RegPath < ActiveResource::Base
4
+ self.site = OfferEngine::Properties.offer_engine_host
5
+
6
+ def get_offers(step, options={})
7
+ offers_hashes = self.get(:get_offers, options.merge({:reg_path_step=>step, :require_match=>false}))
8
+ offers_hashes.map {|offer_hash| OfferEngine::Models::Offer.new.load(offer_hash)}
9
+ end
10
+ end
11
+ end
12
+ end
@@ -0,0 +1,7 @@
1
+ module OfferEngine
2
+ module Models
3
+ class Submission < ActiveResource::Base
4
+ self.site = OfferEngine::Properties.offer_engine_host
5
+ end
6
+ end
7
+ end
@@ -0,0 +1,20 @@
1
+ module OfferEngine
2
+ module Models
3
+ class User < ActiveResource::Base
4
+ self.site = OfferEngine::Properties.offer_engine_host
5
+
6
+ class << self
7
+ def search(email)
8
+ user = self.get(:search, :email=>email)
9
+ User.new.load(user)
10
+ end
11
+ end
12
+
13
+ def get_offers(options={})
14
+ offers_hashes = self.get(:get_offers, options.merge({:require_match=>true}))
15
+ offers_hashes.map {|offer_hash| OfferEngine::Models::Offer.new.load(offer_hash)}
16
+ end
17
+
18
+ end
19
+ end
20
+ end
@@ -0,0 +1,43 @@
1
+ module OfferEngine
2
+ module Properties
3
+ def self.offer_engine_host
4
+ @offer_engine_host || ""
5
+ end
6
+
7
+ def self.offer_engine_get_offers_path
8
+ @offer_engine_get_offers_path || ""
9
+ end
10
+
11
+ def self.offer_engine_submit_offer_path
12
+ @offer_engine_submit_offer_path || ""
13
+ end
14
+
15
+ def self.offer_engine_long_form_path
16
+ @offer_engine_long_form_path || ""
17
+ end
18
+
19
+ def self.offer_engine_host=(host)
20
+ @offer_engine_host = host
21
+ end
22
+
23
+ def self.offer_engine_get_offers_path=(path)
24
+ @offer_engine_get_offers_path = path
25
+ end
26
+
27
+ def self.offer_engine_submit_offer_path=(path)
28
+ @offer_engine_submit_offer_path = path
29
+ end
30
+
31
+ def self.offer_engine_long_form_path=(path)
32
+ @offer_engine_long_form_path = path
33
+ end
34
+
35
+ def self.source
36
+ @source || ""
37
+ end
38
+
39
+ def self.source=(in_source)
40
+ @source = in_source
41
+ end
42
+ end
43
+ end
@@ -0,0 +1,161 @@
1
+ require File.dirname(__FILE__) + "/offer_engine/client"
2
+ # require File.dirname(__FILE__) + "/models/reg_path"
3
+ require File.dirname(__FILE__) + "/mailer/reg_path_mailer"
4
+ require File.dirname(__FILE__) + "/helpers/reg_path_helper"
5
+
6
+
7
+ module ActionController
8
+ module Acts
9
+ module RegPath
10
+
11
+ class RegPathException < Exception; end;
12
+
13
+ def self.append_features(base) #:nodoc:
14
+ super
15
+ base.extend(ClassMethods)
16
+ end
17
+
18
+ module ClassMethods
19
+ #Creates the actions and methods necessary for this controller to be a RegPath.
20
+ #Specifically this generates the *offers* action which handles moving a user through the reg path.
21
+ #Entry into the RegPath can be initiated by calling the begin_reg_path method.
22
+ #Controllers using this act must override the after_reg_path callback or supply the :after option to define what action (render, redirect, etc.) should be taken when the reg path is completed.
23
+ #A :setup_offers before_filter is provided for extension by including Controller. Any setup of params to be sent to the offer engine should be done here, in the @reg_path_options member variable.
24
+ def acts_as_reg_path(reg_path_name_or_sym, options={})
25
+ @reg_path_name_or_sym = reg_path_name_or_sym
26
+ @reg_path_setup_options = options
27
+ @reg_path_setup_options[:after] ||= :after_reg_path
28
+
29
+ include ActionController::Acts::RegPath::InstanceMethods
30
+ before_filter :setup_offers, :only=>:offers
31
+ helper RegPathHelper
32
+ end
33
+
34
+ def reg_path_setup_options
35
+ @reg_path_setup_options
36
+ end
37
+
38
+ def reg_path_name_or_sym
39
+ @reg_path_name_or_sym
40
+ end
41
+ end #ClassMethods
42
+
43
+ module InstanceMethods
44
+ #Action responsible for navigating user through reg path. Will continually retrieve and display the next offer in the reg path.
45
+ #Posts to this action are submitted to the OfferEngine and any confirmation page returned by the OfferEngine is displayed inline.
46
+ #When no offers are returned, the after_reg_path callback or the method specified by the :after option to acts_as_reg_path is fired.
47
+ def offers
48
+ setup_omniture
49
+ return if request.post? && handle_post
50
+
51
+ more_offers = get_and_show_next_offer
52
+ self.class.reg_path_setup_options[:after].to_proc.call(self) unless more_offers
53
+ end
54
+
55
+ protected
56
+ #Either this method should be overwritten by the including class, or :after should be used when calling acts_as_reg_path
57
+ def after_reg_path
58
+ raise RegPathException.new("The after_reg_path lifecycle hook has not been implemented in #{self.class} or the :after option was not passed to acts_as_reg_path.")
59
+ end
60
+
61
+ def setup_offers;end
62
+
63
+ def go_to_offers; return false; end
64
+
65
+ def reg_path_mail_setup
66
+ @reg_path_mail_params = {}
67
+ end
68
+
69
+ private
70
+ #Initiate the reg path. This will clear the reg_path session and redirect into the offers action.
71
+ def begin_reg_path
72
+ clear_reg_path_session
73
+ go_to_offers || redirect_to(:action=>:offers)
74
+ end
75
+
76
+ #Retrieve the next offer from the OfferEngine and display it using the template that matches the offer's type.
77
+ #Returns false if there are no offers returned from the OfferEngine
78
+ def get_and_show_next_offer
79
+ @step = session[:reg_path_step] || 0
80
+ session[:reg_path_step] = @step + 1
81
+
82
+ return false unless next_offers
83
+
84
+ session[:reg_path_processed_offers] ||= []
85
+ session[:reg_path_processed_offers] += @offers.map(&:id)
86
+
87
+ offer_type_name = @offers.first.offer_type_name
88
+ session[:reg_path_offer_type] = offer_type_name
89
+ render :action=>offer_type_name and return true
90
+ end
91
+
92
+ def next_offers
93
+ reg_path = OfferEngine::Models::RegPath.find(reg_path_name)
94
+ @offers = reg_path.get_offers(@step, reg_path_options)
95
+ @num_steps = session[:reg_path_num_steps] ||= reg_path.num_steps
96
+ @offers.empty? ? false : @offers
97
+ end
98
+
99
+ def clear_reg_path_session
100
+ session[:reg_path_step] = nil
101
+ session[:reg_path_num_steps] = nil
102
+ session[:reg_path_offer_type] = nil
103
+ session[:reg_path_processed_offers] = nil
104
+ end
105
+
106
+ def handle_post
107
+ @submission = offer_engine.submit_to_offer_engine(params.merge({:reg_path_offer_type=>session[:reg_path_offer_type]}))
108
+ return false unless @submission
109
+
110
+ @last_offer = @submission.offer
111
+ begin
112
+ reg_path_mail_setup and RegPathMailer.__send__("deliver_#{@last_offer.email_template}", @reg_path_mail_params) if @last_offer.email_template?
113
+ rescue
114
+ if logger
115
+ logger.error "Error while sending RegPath email: #{$!}"
116
+ else
117
+ raise $!
118
+ end
119
+ end
120
+
121
+ @confirmation_page = @last_offer.confirmation_page
122
+ render :action=>:confirmation_page and return true unless @confirmation_page.blank?
123
+ end
124
+
125
+ def offer_engine
126
+ @offer_engine ||= OfferEngine::Client.new
127
+ end
128
+
129
+ def reg_path_name
130
+ reg_path_name_or_sym = self.class.reg_path_name_or_sym
131
+ if reg_path_name_or_sym.is_a?(Symbol)
132
+ reg_path_name_or_sym.to_proc.call(self)
133
+ elsif reg_path_name_or_sym.is_a?(String)
134
+ reg_path_name_or_sym
135
+ else
136
+ raise RegPathException.new("No reg path name or method specified")
137
+ end
138
+ end
139
+
140
+ def reg_path_options
141
+ @reg_path_options ||= {}
142
+ if (excludes = session[:reg_path_processed_offers])
143
+ @reg_path_options.merge!({:exclude=>excludes})
144
+ end
145
+ @reg_path_options
146
+ end
147
+
148
+ #Omniture event tracking starts at event11 and currently the last view event is event14.
149
+ #If in the future we expand the omniture events tracking, this will need to be updated.
150
+ def setup_omniture
151
+ step = session[:reg_path_step] || 0
152
+ @omniture_products = "Reg Path; #{@omniture_product_name}"
153
+ end
154
+ end #InstanceMethods
155
+ end
156
+ end
157
+ end
158
+
159
+ ActionController::Base.class_eval do
160
+ include ActionController::Acts::RegPath
161
+ end
File without changes
@@ -0,0 +1,3 @@
1
+ <?xml version="1.0" encoding="UTF-8"?>
2
+ <offers type="array">
3
+ </offers>
File without changes
File without changes
data/test/offers.xml ADDED
@@ -0,0 +1,33 @@
1
+ <?xml version="1.0" encoding="UTF-8"?>
2
+ <offers type="array">
3
+ <offer>
4
+ <created-at type="datetime">2008-11-24T22:46:00Z</created-at>
5
+ <description>Default house form</description>
6
+ <id type="integer">10</id>
7
+ <name>House Form</name>
8
+ <offer-type-id type="integer">2</offer-type-id>
9
+
10
+ <show-only-on-match type="boolean">false</show-only-on-match>
11
+ <submitter-id type="integer" nil="true"></submitter-id>
12
+ <updated-at type="datetime">2008-11-24T22:46:00Z</updated-at>
13
+ <url>house.html</url>
14
+ <weight type="integer">1</weight>
15
+ <offer-type-name>long_form</offer-type-name>
16
+ <email-template>house_form</email-template>
17
+ </offer>
18
+ <offer>
19
+ <created-at type="datetime">2008-11-24T22:46:00Z</created-at>
20
+ <description>iPort long form</description>
21
+ <id type="integer">11</id>
22
+ <name>iPort Test Long Form</name>
23
+ <offer-type-id type="integer">2</offer-type-id>
24
+
25
+ <show-only-on-match type="boolean">false</show-only-on-match>
26
+ <submitter-id type="integer">1</submitter-id>
27
+ <updated-at type="datetime">2008-11-25T05:34:06Z</updated-at>
28
+ <url>iport.html</url>
29
+ <weight type="integer">1</weight>
30
+ <offer-type-name>long_form</offer-type-name>
31
+ <email-template>house_form</email-template>
32
+ </offer>
33
+ </offers>
data/test/reg_path.xml ADDED
@@ -0,0 +1,10 @@
1
+ <?xml version="1.0" encoding="UTF-8"?>
2
+ <reg-path>
3
+ <created-at type="datetime">2008-12-08T19:27:37Z</created-at>
4
+ <description nil="true"></description>
5
+ <id type="integer">4</id>
6
+ <name>default</name>
7
+ <updated-at type="datetime">2008-12-08T19:27:37Z</updated-at>
8
+ <num-steps>3</num-steps>
9
+
10
+ </reg-path>
data/test/routes.rb ADDED
@@ -0,0 +1,4 @@
1
+ ActionController::Routing::Routes.draw do |map|
2
+
3
+ map.connect ':controller/:action/:id'
4
+ end
File without changes
@@ -0,0 +1,24 @@
1
+ <?xml version="1.0" encoding="UTF-8"?>
2
+ <submission>
3
+ <created_at type="datetime">2008-12-08T14:57:30Z</created_at>
4
+ <id type="integer">28</id>
5
+ <offer_id type="integer">11</offer_id>
6
+ <sent_at type="datetime" nil="true"></sent_at>
7
+ <updated_at type="datetime">2008-12-08T14:57:30Z</updated_at>
8
+ <user_id type="integer">1</user_id>
9
+ <offer>
10
+ <confirmation_page>conf_page.html</confirmation_page>
11
+ <created_at type="datetime">2008-12-08T14:57:30Z</created_at>
12
+ <description nil="true"></description>
13
+ <id type="integer">11</id>
14
+ <name>Long form with confirmation page</name>
15
+ <offer_type_id type="integer">3</offer_type_id>
16
+ <show_only_on_match type="boolean">false</show_only_on_match>
17
+ <submitter_id type="integer" nil="true"></submitter_id>
18
+ <updated_at type="datetime">2008-12-08T14:57:30Z</updated_at>
19
+ <url nil="true"></url>
20
+ <weight type="integer">1</weight>
21
+ <offer_type_name>long_form</offer_type_name>
22
+ <email_template>house_form</email_template>
23
+ </offer>
24
+ </submission>
@@ -0,0 +1,24 @@
1
+ <?xml version="1.0" encoding="UTF-8"?>
2
+ <submission>
3
+ <created_at type="datetime">2008-12-08T14:57:30Z</created_at>
4
+ <id type="integer">28</id>
5
+ <offer_id type="integer">11</offer_id>
6
+ <sent_at type="datetime" nil="true"></sent_at>
7
+ <updated_at type="datetime">2008-12-08T14:57:30Z</updated_at>
8
+ <user_id type="integer">1</user_id>
9
+ <offer>
10
+ <confirmation_page></confirmation_page>
11
+ <created_at type="datetime">2008-12-08T14:57:30Z</created_at>
12
+ <description nil="true"></description>
13
+ <id type="integer">11</id>
14
+ <name>Long form with confirmation page</name>
15
+ <offer_type_id type="integer">3</offer_type_id>
16
+ <show_only_on_match type="boolean">false</show_only_on_match>
17
+ <submitter_id type="integer" nil="true"></submitter_id>
18
+ <updated_at type="datetime">2008-12-08T14:57:30Z</updated_at>
19
+ <url nil="true"></url>
20
+ <weight type="integer">1</weight>
21
+ <offer_type_name>long_form</offer_type_name>
22
+ <email_confirmation_fragment></email_confirmation_fragment>
23
+ </offer>
24
+ </submission>
@@ -0,0 +1,7 @@
1
+ require 'stringio'
2
+ require 'test/unit'
3
+ require File.dirname(__FILE__) + '/../lib/reg_path'
4
+ require "action_controller/test_case"
5
+ require 'action_controller/test_process'
6
+ require "routes"
7
+ require "mocha"
@@ -0,0 +1,95 @@
1
+ require 'test_helper'
2
+ require "mocha"
3
+ require "shoulda"
4
+
5
+ class OfferEngineClientTest < ActiveSupport::TestCase
6
+
7
+ context "An OfferEngineClient, @offer_engine," do
8
+ setup do
9
+ @offer_engine = OfferEngine::Client.new
10
+ end
11
+
12
+ context "submitting a long offer form to the OfferEngine" do
13
+ setup do
14
+ @mock = mock_submit
15
+ @params = {:reg_path_offer_type=>"long_form", :test=>"test", :x=>"x"}
16
+ end
17
+
18
+ should "submit to OfferEngine once" do
19
+ @mock.once
20
+ @offer_engine.submit_to_offer_engine(@params)
21
+ end
22
+
23
+ context "that has a confirmation form" do
24
+ setup do
25
+ # @mock.returns(mock('response', :body=>File.new(File.dirname(__FILE__) + "/submission.xml", 'r')))
26
+ end
27
+
28
+ should "return a Submission representing the succesful submission" do
29
+ assert_equal OfferEngine::Models::Submission, @offer_engine.submit_to_offer_engine(@params).class
30
+ end
31
+
32
+ should "return a Submission with confirmation_page equal to 'iport_confirmation.html'" do
33
+ submission = @offer_engine.submit_to_offer_engine(@params)
34
+ assert_equal "conf_page.html", submission.offer.confirmation_page
35
+
36
+ end
37
+ end
38
+ end #submitting a long offer form to the OfferEngine
39
+
40
+ context "submitting 3 short offer forms to the OfferEngine" do
41
+ setup do
42
+ @mock = mock_submit
43
+ @params = {:reg_path_offer_type=>"short_form", "offer_1"=>"test", "offer_2"=>"x", "offer_3"=>"y"}
44
+ end
45
+
46
+ should "submit to OfferEngine once" do
47
+ @mock.times(3)
48
+ @offer_engine.submit_to_offer_engine(@params)
49
+ end
50
+ end #submitting a long offer form to the OfferEngine
51
+
52
+ context "adding data for a user" do
53
+ setup do
54
+ @email = "test@test.com"
55
+ @keys = ["condition", "medication"]
56
+ @values = ["diabetes", "adhd"]
57
+ end
58
+
59
+ should "call to the offer engine with query string ?email=test@test.com&keys[]=condition&keys[]=medication&values[]=diabetes&values[]=adhd" do
60
+ uri = URI.parse("#{OfferEngine::Properties.offer_engine_host}/data_store/add_data?email=test@test.com&keys%5B%5D=condition&keys%5B%5D=medication&values%5B%5D=diabetes&values%5B%5D=adhd")
61
+ Net::HTTP.expects(:get).with(responds_with(:path, uri.path)).returns(Net::HTTPSuccess.new("","",""))
62
+ assert @offer_engine.add_data(@email, @keys, @values)
63
+ end
64
+
65
+ context "in hash form" do
66
+ setup do
67
+ @hash = {@keys[0] => @values[0], @keys[1] => @values[1]}
68
+ end
69
+
70
+ should "call to the offer engine with query string ?email=test@test.com&keys[]=condition&keys[]=medication&values[]=diabetes&values[]=adhd" do
71
+ uri = URI.parse("#{OfferEngine::Properties.offer_engine_host}/data_store/add_data?email=test@test.com&keys%5B%5D=condition&keys%5B%5D=medication&values%5B%5D=diabetes&values%5B%5D=adhd")
72
+ Net::HTTP.expects(:get).with(responds_with(:path, uri.path)).returns(Net::HTTPSuccess.new("","",""))
73
+ assert @offer_engine.add_data(@email, @keys, @values)
74
+ end
75
+ end #in hash form
76
+ end #adding data for a user
77
+ end # An OfferEngineClient, @offer_engine,
78
+
79
+
80
+ private
81
+ def stub_open(successful=true, with_offers=true, xml_filename=nil)
82
+ stub = OfferEngine::Client.any_instance.stubs(:open)
83
+ if successful
84
+ filename = xml_filename || (with_offers ? "offers" : "empty_offers")
85
+ stub.returns(File.new(File.dirname(__FILE__) + "/#{filename}.xml", 'r'))
86
+ else
87
+ stub.raises(OpenURI::HTTPError.new("Error", ""))
88
+ end
89
+ end
90
+
91
+ def mock_submit
92
+ OfferEngine::Properties.offer_engine_submit_offer_path = "http://test.com/test"
93
+ Net::HTTP.any_instance.expects(:start).returns(stub('response', :body=>File.read(File.dirname(__FILE__) + "/submission.xml")))
94
+ end
95
+ end
@@ -0,0 +1,204 @@
1
+ require 'test_helper'
2
+ require "lib/reg_path"
3
+ require "mocha"
4
+ require "shoulda"
5
+
6
+ class TestController < ActionController::Base
7
+ acts_as_reg_path :determine_reg_path_name, :after=>:reg_path_complete
8
+
9
+ def start
10
+ begin_reg_path
11
+ end
12
+
13
+ def finish
14
+ end
15
+
16
+ def offers_with_view_path
17
+ append_view_path File.dirname(__FILE__) + "/.."
18
+ offers_without_view_path
19
+ end
20
+ alias_method_chain :offers, :view_path
21
+
22
+ protected
23
+ def setup_offers
24
+ @omniture_product_name = "Test"
25
+ end
26
+
27
+ def reg_path_complete
28
+ redirect_to :action=>:finish
29
+ end
30
+
31
+ def determine_reg_path_name
32
+ "test"
33
+ end
34
+
35
+ def reg_path_mail_setup
36
+ @reg_path_mail_params = {:to=>"test@test.com", :from=>"from@from.com", :subject=>"subject"}
37
+ end
38
+ end
39
+
40
+ class RegPathTest < ActionController::TestCase
41
+ tests TestController
42
+
43
+ context "A RegPath controller" do
44
+ setup do
45
+ OfferEngine::Models::RegPath.stubs(:find).returns(OfferEngine::Models::RegPath.new.load(Hash.from_xml(File.read(File.dirname(__FILE__) + "/reg_path.xml"))["reg_path"]))
46
+ @emails = ActionMailer::Base.deliveries
47
+ @emails.clear
48
+ end
49
+
50
+ context "in the action that triggers the reg path" do
51
+ setup do
52
+ get :start
53
+ end
54
+
55
+ should "redirect to offers" do
56
+ assert_redirected_to :action => "offers"
57
+ end
58
+ end #in the action that triggers the reg path
59
+
60
+ context "calling the offers action in a case that returns offers" do
61
+ setup do
62
+ mock_reg_path
63
+ get :offers
64
+ @offer_type = @offers.first.offer_type_name
65
+ end
66
+
67
+ should "render the template for the offer_type of the offer" do
68
+ assert_response :success
69
+ assert_template "test/#{@offer_type}"
70
+ end
71
+
72
+ should "set @offers to the offers returned from OfferEngine" do
73
+ assert_equal @offers, assigns(:offers)
74
+ end
75
+
76
+ should "increment session[:reg_path_step] to 1" do
77
+ assert_equal 1, session[:reg_path_step]
78
+ end
79
+
80
+ should "set session[:reg_path_offer_type] to the offer type" do
81
+ assert_equal @offer_type, session[:reg_path_offer_type]
82
+ end
83
+
84
+ should "add the offer id returned by the OfferEngine to the list of offers to exclude" do
85
+ @offers.each do |offer|
86
+ assert session[:reg_path_processed_offers].include?(offer.id)
87
+ end
88
+ end
89
+
90
+ should "set up omniture products correctly" do
91
+ assert_equal "Reg Path; Test", assigns(:omniture_products)
92
+ end
93
+
94
+ should "set up omniture events correctly" do
95
+ assert_equal "event11", assigns(:omniture_events)
96
+ end
97
+
98
+ context "calling offers action again" do
99
+ setup do
100
+ get :offers
101
+ end
102
+
103
+ should "increment session[:reg_path_step] to 2" do
104
+ assert_equal 2, session[:reg_path_step]
105
+ end
106
+
107
+ should "set up omniture events properly" do
108
+ assert_equal "event14,event13", assigns(:omniture_events)
109
+ end
110
+
111
+ context "calling offers action a third time" do
112
+ setup do
113
+ get :offers
114
+ end
115
+
116
+ should "increment session[:reg_path_step] to 3" do
117
+ assert_equal 3, session[:reg_path_step]
118
+ end
119
+
120
+ should "set up omniture events properly. View events should not exceed the maximum view event in omniture (currently event14)" do
121
+ assert_equal "event14,event13", assigns(:omniture_events)
122
+ end
123
+ end #calling offers action again
124
+ end #calling offers action again
125
+
126
+
127
+
128
+ context "calling the action that starts the reg path again" do
129
+ setup do
130
+ get :start
131
+ end
132
+
133
+ should "clear all session variables" do
134
+ [:reg_path_step, :reg_path_processed_offers, :reg_path_offer_type].each do |sym|
135
+ assert_nil session[sym]
136
+ end
137
+ end
138
+ end #calling the action the starts the reg path again
139
+
140
+ end #calling the offers action in a case that returns offers
141
+
142
+ context "calling the offers action in a case that returns no offers" do
143
+ setup do
144
+ mock_reg_path(false)
145
+ get :offers
146
+ end
147
+
148
+ should "redirect to the finish action" do
149
+ assert_redirected_to :action => "finish"
150
+ end
151
+ end #calling the offers action in a case that returns offers
152
+
153
+ context "posting to the offers action" do
154
+ setup do
155
+ mock_reg_path_submit
156
+ end
157
+
158
+ should "still call RegPath.get_offers" do
159
+ mock_reg_path
160
+ post :offers
161
+ end
162
+
163
+ should "not send an email" do
164
+ mock_reg_path
165
+ assert_no_difference("@emails.size") do
166
+ post :offers
167
+ end
168
+ end
169
+ end #posting to the offers action
170
+
171
+ context "posting to the offers action with an offer that has a confirmation page and email" do
172
+ setup do
173
+ mock_reg_path_submit("confirmation_page.html")
174
+ File.expects(:exists?).returns(false) #ignore the overridden mail templates
175
+ end
176
+
177
+ should "render the confirmation page action" do
178
+ post :offers
179
+ assert_response :success
180
+ assert_template "test/confirmation_page"
181
+ end
182
+
183
+ should "send an email" do
184
+ assert_difference("@emails.size") do
185
+ post :offers
186
+ end
187
+ end
188
+ end #posting to the offers action with an offer that has a confirmation page
189
+
190
+ end #A RegPath controller
191
+
192
+ private
193
+ def mock_reg_path(with_offers = true)
194
+ @offers = with_offers ? Hash.from_xml(File.read(File.dirname(__FILE__) + "/offers.xml"))["offers"] : []
195
+ @offers.map! {|offer| OfferEngine::Models::Offer.new.load(offer)}
196
+ OfferEngine::Models::RegPath.any_instance.expects(:get_offers).at_least_once.returns(@offers)
197
+ end
198
+
199
+ def mock_reg_path_submit(confirmation_page = false)
200
+ filename = confirmation_page ? "submission.xml" : "submission_no_conf.xml"
201
+ OfferEngine::Properties.offer_engine_submit_offer_path = "http://test.com/test"
202
+ Net::HTTP.any_instance.expects(:start).returns(stub('response', :body=>File.read(File.dirname(__FILE__) + "/#{filename}")))
203
+ end
204
+ end
metadata ADDED
@@ -0,0 +1,93 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: gregfitz23-RegPath
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.1
5
+ platform: ruby
6
+ authors:
7
+ - Greg Fitzgerald
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+
12
+ date: 2009-04-26 00:00:00 -07:00
13
+ default_executable: reg_path
14
+ dependencies: []
15
+
16
+ description: TODO
17
+ email: greg_fitz@yahoo.com
18
+ executables:
19
+ - reg_path
20
+ extensions: []
21
+
22
+ extra_rdoc_files:
23
+ - README
24
+ - README.txt
25
+ files:
26
+ - History.txt
27
+ - Manifest.txt
28
+ - README.txt
29
+ - RegPath.gemspec
30
+ - VERSION.yml
31
+ - bin/reg_path
32
+ - lib/reg_path
33
+ - lib/reg_path/_progress_bar.html.erb
34
+ - lib/reg_path/helpers
35
+ - lib/reg_path/helpers/reg_path_helper.rb
36
+ - lib/reg_path/mailer
37
+ - lib/reg_path/mailer/reg_path_mailer
38
+ - lib/reg_path/mailer/reg_path_mailer/house_form.html.erb
39
+ - lib/reg_path/mailer/reg_path_mailer.rb
40
+ - lib/reg_path/models
41
+ - lib/reg_path/offer_engine
42
+ - lib/reg_path/offer_engine/client.rb
43
+ - lib/reg_path/offer_engine/models
44
+ - lib/reg_path/offer_engine/models/offer.rb
45
+ - lib/reg_path/offer_engine/models/reg_path.rb
46
+ - lib/reg_path/offer_engine/models/submission.rb
47
+ - lib/reg_path/offer_engine/models/user.rb
48
+ - lib/reg_path/properties.rb
49
+ - lib/reg_path/reg_path.rb
50
+ - lib/reg_path.rb
51
+ - test/confirmation_page.html.erb
52
+ - test/empty_offers.xml
53
+ - test/house_form.html.erb
54
+ - test/long_form.html.erb
55
+ - test/offers.xml
56
+ - test/reg_path.xml
57
+ - test/routes.rb
58
+ - test/short_form.html.erb
59
+ - test/submission.xml
60
+ - test/submission_no_conf.xml
61
+ - test/test_helper.rb
62
+ - test/test_offer_engine_client.rb
63
+ - test/test_reg_path.rb
64
+ - README
65
+ has_rdoc: true
66
+ homepage: ""
67
+ post_install_message:
68
+ rdoc_options:
69
+ - --inline-source
70
+ - --charset=UTF-8
71
+ require_paths:
72
+ - lib
73
+ required_ruby_version: !ruby/object:Gem::Requirement
74
+ requirements:
75
+ - - ">="
76
+ - !ruby/object:Gem::Version
77
+ version: "0"
78
+ version:
79
+ required_rubygems_version: !ruby/object:Gem::Requirement
80
+ requirements:
81
+ - - ">="
82
+ - !ruby/object:Gem::Version
83
+ version: "0"
84
+ version:
85
+ requirements: []
86
+
87
+ rubyforge_project:
88
+ rubygems_version: 1.2.0
89
+ signing_key:
90
+ specification_version: 2
91
+ summary: TODO
92
+ test_files: []
93
+