Only allow registration with registration plans

Stephen Paul Weber created

Change summary

bin/sim_job               |  3 ++-
config-schema.dhall       |  3 ++-
config.dhall.sample       |  3 ++-
lib/plan.rb               | 11 +++++++++++
lib/registration.rb       | 16 ++++++++--------
test/test_helper.rb       | 11 ++++++++++-
test/test_registration.rb | 23 +++++++++++++++++++++++
7 files changed, 58 insertions(+), 12 deletions(-)

Detailed changes

bin/sim_job 🔗

@@ -26,7 +26,8 @@ SCHEMA = "{
 		messages: < limited: { included: Natural, price: Natural } | unlimited >,
 		minutes: < limited: { included: Natural, price: Natural } | unlimited >,
 		monthly_price : Natural,
-		name : Text
+		name : Text,
+		allow_register: Bool
 	}
 }"
 

config-schema.dhall 🔗

@@ -35,7 +35,8 @@
 , payable : Text
 , plans :
     List
-      { currency : < CAD | USD >
+      { allow_register : Bool
+      , currency : < CAD | USD >
       , messages :
           < limited : { included : Natural, price : Natural } | unlimited >
       , minutes :

config.dhall.sample 🔗

@@ -56,7 +56,8 @@ in
 			messages = <
 				unlimited |
 				limited: { included: Natural, price: Natural }
-			>.unlimited
+			>.unlimited,
+			allow_register = True
 		}
 	],
 	sims = {

lib/plan.rb 🔗

@@ -10,6 +10,13 @@ class Plan
 		new(plan)
 	end
 
+	def self.for_registration(plan_name)
+		plan = self.for(plan_name)
+		raise "No registration plan by that name" unless plan.allow_register?
+
+		plan
+	end
+
 	def initialize(plan)
 		@plan = plan
 	end
@@ -26,6 +33,10 @@ class Plan
 		BigDecimal(@plan[:monthly_price]) / 10000
 	end
 
+	def allow_register?
+		!!@plan[:allow_register]
+	end
+
 	def merchant_account
 		CONFIG[:braintree][:merchant_accounts].fetch(currency) do
 			raise "No merchant account for this currency"

lib/registration.rb 🔗

@@ -127,8 +127,8 @@ class Registration
 
 		def save_customer_plan(iq, code)
 			ParentCodeRepo.new(REDIS).find(code).then do |parent|
-				plan_name = iq.form.field("plan_name").value.to_s
-				@customer = @customer.with_plan(plan_name, parent_customer_id: parent)
+				plan = Plan.for_registration(iq.form.field("plan_name").value.to_s)
+				@customer = @customer.with_plan(plan.name, parent_customer_id: parent)
 				@customer.save_plan!
 			end
 		end
@@ -167,13 +167,13 @@ class Registration
 			end
 
 			def activate(iq)
-				plan_name = iq.form.field("plan_name").value
+				plan = Plan.for_registration(iq.form.field("plan_name").value)
 				code = iq.form.field("code")&.value
 				EMPromise.all([
 					@parent_code_repo.find(code),
 					REDIS.sadd("google_play_userids", @google_play_userid)
 				]).then { |(parent, _)|
-					save_active_plan(plan_name, parent)
+					save_active_plan(plan, parent)
 				}.then do
 					use_referral_code(code)
 				end
@@ -181,8 +181,8 @@ class Registration
 
 		protected
 
-			def save_active_plan(plan_name, parent)
-				@customer = @customer.with_plan(plan_name, parent_customer_id: parent)
+			def save_active_plan(plan, parent)
+				@customer = @customer.with_plan(plan.name, parent_customer_id: parent)
 				@customer.activate_plan_starting_now
 			end
 
@@ -217,8 +217,8 @@ class Registration
 			end
 
 			def next_step(iq)
-				plan_name = iq.form.field("plan_name").value.to_s
-				@customer = customer.with_plan(plan_name)
+				plan = Plan.for_registration(iq.form.field("plan_name").value.to_s)
+				@customer = customer.with_plan(plan.name)
 				EMPromise.resolve(nil).then { activate }.then do
 					Finish.new(customer, tel).write
 				end

test/test_helper.rb 🔗

@@ -76,12 +76,21 @@ CONFIG = {
 			currency: :USD,
 			monthly_price: 10000,
 			messages: :unlimited,
-			minutes: { included: 10440, price: 87 }
+			minutes: { included: 10440, price: 87 },
+			allow_register: true
 		},
 		{
 			name: "test_bad_currency",
 			currency: :BAD
 		},
+		{
+			name: "test_usd_no_register",
+			currency: :USD,
+			monthly_price: 10000,
+			messages: :unlimited,
+			minutes: { included: 10440, price: 87 },
+			allow_register: false
+		},
 		{
 			name: "test_cad",
 			currency: :CAD,

test/test_registration.rb 🔗

@@ -157,6 +157,29 @@ class RegistrationTest < Minitest::Test
 		end
 		em :test_write
 
+		def test_write_bad_plan
+			Command::COMMAND_MANAGER.expect(
+				:write,
+				EMPromise.resolve(Blather::Stanza::Iq::Command.new.tap { |iq|
+					iq.form.fields = [{ var: "plan_name", value: "test_usd_no_register" }]
+				}),
+				[Matching.new do |iq|
+					assert_equal :form, iq.form.type
+					assert_equal(
+						"You've selected +15555550000 as your JMP number.",
+						iq.form.instructions.lines.first.chomp
+					)
+				end]
+			)
+			assert_equal(
+				"No registration plan by that name",
+				execute_command { @activation.write.catch { |e| e } }.message
+			)
+			assert_mock Command::COMMAND_MANAGER
+			assert_mock @customer
+		end
+		em :test_write_bad_plan
+
 		def test_write_with_code
 			Command::COMMAND_MANAGER.expect(
 				:write,