diff --git a/lib/blather_ext.rb b/lib/blather_ext.rb index a6b5f51d98fe9e7e25ac015eb3572f96530a9aa6..265e84a62fc783bfdd0e547595eb171944c19ca9 100644 --- a/lib/blather_ext.rb +++ b/lib/blather_ext.rb @@ -3,6 +3,8 @@ require "securerandom" module Blather + ADDRESSES_NS = "http://jabber.org/protocol/address" + class JID def with(node: self.node, domain: self.domain, resource: self.resource) self.class.new(node, domain, resource) diff --git a/lib/customer_usage.rb b/lib/customer_usage.rb index a614a081425bbbfee1aba3cc41c16975f9829d72..2a6dd0c6e016e617a4ed4d16de38e25cd28e7c69 100644 --- a/lib/customer_usage.rb +++ b/lib/customer_usage.rb @@ -28,7 +28,8 @@ class CustomerUsage ) end - def incr_message_usage(amount=1, body=nil) + def incr_message_usage(recipients:, body: nil) + amount = recipients.each_slice(10).count today = Time.now.utc.to_date EMPromise.all([ expire_message_usage, diff --git a/sgx_jmp.rb b/sgx_jmp.rb index 08dd5d574516df17553b78166cd340f4674c3024..6bf141ad87e3e6c373f619f87bd9022ff40f3965 100644 --- a/sgx_jmp.rb +++ b/sgx_jmp.rb @@ -291,7 +291,6 @@ before nil, to: /\Acustomer_/, from: /(\A|@)#{FROM_BACKEND}(\/|\Z)/ do |s| halt end -ADDRESSES_NS = "http://jabber.org/protocol/address" message( to: /\A#{CONFIG[:component][:jid]}\Z/, from: /(\A|@)#{FROM_BACKEND}(\/|\Z)/ @@ -427,10 +426,12 @@ message do |m| next customer.stanza_from(m) unless billable_message(m) expired_guard(customer) - EMPromise.all([ TrustLevelRepo.new.find(customer), - customer.incr_message_usage(1, m.body) + customer.incr_message_usage( + recipients: m.addresses.to_a, + body: m.body + ) ]).then { |(tl, usage)| usage_guard(m, m.to.node.to_s, customer, tl, usage) }.then do diff --git a/test/test_customer_usage.rb b/test/test_customer_usage.rb new file mode 100644 index 0000000000000000000000000000000000000000..921122a8a89d577a78263077e4d08b94da8e5a48 --- /dev/null +++ b/test/test_customer_usage.rb @@ -0,0 +1,95 @@ +# frozen_string_literal: true + +require "test_helper" + +require "customer_usage" + +CustomerUsage::REDIS = Minitest::Mock.new + +class CustomerUsageTest < Minitest::Test + def setup + @customer_usage = CustomerUsage.new("customer") + end + + def test_incr_message_usage_counts_ten_recipients_as_one_message + CustomerUsage::REDIS.expect(:zremrangebylex, []) do |*args| + cust_key, dash, * = args + assert_equal "jmp_customer_outbound_messages-customer", cust_key + assert_equal "-", dash + end + CustomerUsage::REDIS.expect(:zincrby, 1) do |*args| + cust_key, amount, * = args + assert_equal "jmp_customer_outbound_messages-customer", cust_key + assert_equal 1, amount + end + + result = @customer_usage.incr_message_usage( + recipients: Array.new(10) { |i| "#{i}@example.com" } + ).sync + + assert_equal result, { today: 1, body: 0 } + CustomerUsage::REDIS.verify + end + em :test_incr_message_usage_counts_ten_recipients_as_one_message + + def test_incr_message_usage_counts_nine_recipients_as_one_message + CustomerUsage::REDIS.expect(:zremrangebylex, []) do |*args| + cust_key, dash, * = args + assert_equal "jmp_customer_outbound_messages-customer", cust_key + assert_equal "-", dash + end + CustomerUsage::REDIS.expect(:zincrby, 1) do |*args| + cust_key, amount, * = args + assert_equal "jmp_customer_outbound_messages-customer", cust_key + assert_equal 1, amount + end + + result = @customer_usage.incr_message_usage( + recipients: Array.new(9) { |i| "#{i}@example.com" } + ).sync + + assert_equal result, { today: 1, body: 0 } + CustomerUsage::REDIS.verify + end + em :test_incr_message_usage_counts_nine_recipients_as_one_message + + def test_incr_message_usage + CustomerUsage::REDIS.expect(:zremrangebylex, []) do |*args| + cust_key, dash, * = args + assert_equal "jmp_customer_outbound_messages-customer", cust_key + assert_equal "-", dash + end + CustomerUsage::REDIS.expect(:zincrby, 2) do |*args| + cust_key, amount, * = args + assert_equal "jmp_customer_outbound_messages-customer", cust_key + assert_equal 2, amount + end + + # Literally no way to make this fit + # rubocop:disable Metrics/LineLength + expected_key = "jmp_outbound_body-dffd6021bb2bd5b0af676290809ec3a53191dd81c7f70a4b28688a362182986f" + # rubocop:enable Metrics/LineLength + + CustomerUsage::REDIS.expect(:incrby, 2) do |*args| + body_key, amount = args + assert_equal body_key, expected_key + assert_equal amount, 2 + end + + CustomerUsage::REDIS.expect(:expire, 2) do |*args| + body_key, timeout = args + + assert_equal body_key, expected_key + assert_equal timeout, 180 + end + + result = @customer_usage.incr_message_usage( + recipients: Array.new(11) { |i| "#{i}@example.com" }, + body: "Hello, World!" + ).sync + + assert_equal result, { today: 2, body: 2 } + CustomerUsage::REDIS.verify + end + em :test_incr_message_usage +end