diff --git a/lib/amplitude_api/event.rb b/lib/amplitude_api/event.rb index 24d3cf5..4afafbe 100644 --- a/lib/amplitude_api/event.rb +++ b/lib/amplitude_api/event.rb @@ -20,13 +20,34 @@ class Event # @return [ String ] IP address of the user attr_accessor :ip + + # @!attribute [ rw ] price + # @return [ String ] (required for revenue data) price of the item purchased + attr_accessor :price + + # @!attribute [ rw ] quantity + # @return [ String ] (required for revenue data, defaults to 1 if not specified) quantity of the item purchased + attr_accessor :quantity + + # @!attribute [ rw ] product_id + # @return [ String ] an identifier for the product. (Note: you must send a price and quantity with this field) + attr_accessor :product_id + + # @!attribute [ rw ] revenue_type + # @return [ String ] type of revenue. (Note: you must send a price and quantity with this field) + attr_accessor :revenue_type + # Create a new Event # # @param [ String ] user_id a user_id to associate with the event # @param [ String ] event_type a name for the event # @param [ Hash ] event_properties various properties to attach to the event # @param [ Time ] Time that the event occurred (defaults to now) - # @param [ String ] IP address of the user + # @param [ Double ] price (optional, but required for revenue data) price of the item purchased + # @param [ Integer ] quantity (optional, but required for revenue data) quantity of the item purchased + # @param [ String ] product_id (optional) an identifier for the product. + # @param [ String ] revenue_type (optional) type of revenue + def initialize(options = {}) self.user_id = options.fetch(:user_id, '') self.event_type = options.fetch(:event_type, '') @@ -34,15 +55,21 @@ def initialize(options = {}) self.user_properties = options.fetch(:user_properties, {}) self.time = options[:time] self.ip = options.fetch(:ip, '') + + self.price = options[:price] + self.quantity = options[:quantity] || 1 if self.price + self.product_id = options[:product_id] + self.revenue_type = options[:revenue_type] + validate_revenue_arguments end def user_id=(value) @user_id = - if value.respond_to?(:id) - value.id - else - value || AmplitudeAPI::USER_WITH_NO_ACCOUNT - end + if value.respond_to?(:id) + value.id + else + value || AmplitudeAPI::USER_WITH_NO_ACCOUNT + end end # @return [ Hash ] A serialized Event @@ -56,6 +83,10 @@ def to_hash serialized_event[:user_properties] = user_properties serialized_event[:time] = formatted_time if time serialized_event[:ip] = ip if ip + serialized_event[:productId] = product_id if product_id + serialized_event[:revenueType] = revenue_type if revenue_type + serialized_event[:quantity] = quantity if quantity + serialized_event[:price] = price if price serialized_event end @@ -75,5 +106,13 @@ def ==(other) def formatted_time time.to_i * 1_000 end + + def validate_revenue_arguments + return if self.price + raise ArgumentError.new("You must provide a price in order to use the product_id") if self.product_id + raise ArgumentError.new("You must provide a price in order to use the revenue_type") if self.revenue_type + end + end + end diff --git a/spec/lib/amplitude_api/event_spec.rb b/spec/lib/amplitude_api/event_spec.rb index 716b520..07eb4df 100644 --- a/spec/lib/amplitude_api/event_spec.rb +++ b/spec/lib/amplitude_api/event_spec.rb @@ -39,6 +39,30 @@ end end + describe 'init' do + context 'the user does not send in a price' do + it 'raises an error if the user sends in a product_id' do + expect { + described_class.new( + user_id: 123, + event_type: 'bad event', + product_id: "hopscotch.4lyfe" + ) + }.to raise_error(ArgumentError) + end + + it 'raises an error if the user sends in a revenue_type' do + expect { + described_class.new( + user_id: 123, + event_type: 'bad event', + revenue_type: "tax return" + ) + }.to raise_error(ArgumentError) + end + end + end + describe '#body' do it 'includes the event type' do event = described_class.new( @@ -57,22 +81,93 @@ expect(event.to_hash[:event_properties]).to eq(abc: :def) end - it 'includes a time for the event' do - time = Time.parse('2016-01-01 00:00:00 -0000') - event = described_class.new( - user_id: 123, - event_type: 'clicked on home', - time: time - ) - expect(event.to_hash[:time]).to eq(1_451_606_400_000) + describe 'time' do + it 'includes a time for the event' do + time = Time.parse('2016-01-01 00:00:00 -0000') + event = described_class.new( + user_id: 123, + event_type: 'clicked on home', + time: time + ) + expect(event.to_hash[:time]).to eq(1_451_606_400_000) + end + + it 'does not include time if it is not set' do + event = described_class.new( + user_id: 123, + event_type: 'clicked on home' + ) + expect(event.to_hash).not_to have_key(:time) + end + end - it 'does not include time if it is not set' do - event = described_class.new( - user_id: 123, - event_type: 'clicked on home' - ) - expect(event.to_hash).not_to have_key(:time) + describe 'revenue params' do + it 'includes the price if it is set' do + price = 100000.99 + event = described_class.new( + user_id: 123, + event_type: 'clicked on home', + price: price + ) + expect(event.to_hash[:price]).to eq(price) + end + + it 'sets the quantity to 1 if the price is set and the quantity is not' do + price = 100000.99 + event = described_class.new( + user_id: 123, + event_type: 'clicked on home', + price: price + ) + expect(event.to_hash[:quantity]).to eq(1) + end + + it "includes the quantity if it is set" do + quantity = 100 + event = described_class.new( + user_id: 123, + event_type: 'clicked on home', + quantity: quantity, + price: 10.99 + ) + expect(event.to_hash[:quantity]).to eq(quantity) + end + + + it 'includes the productID if set' do + product_id = "hopscotch.subscriptions.rule" + event = described_class.new( + user_id: 123, + event_type: 'clicked on home', + price: 199.99, + product_id: product_id + ) + expect(event.to_hash[:productId]).to eq(product_id) + end + + it 'includes the revenueType if set' do + revenue_type = "income" + event = described_class.new( + user_id: 123, + event_type: 'clicked on home', + price: 199.99, + revenue_type: revenue_type + ) + expect(event.to_hash[:revenueType]).to eq(revenue_type) + end + + it "does not include revenue params if they are not set" do + event = described_class.new( + user_id: 123, + event_type: 'clicked on home', + ) + expect(event.to_hash).not_to have_key(:quantity) + expect(event.to_hash).not_to have_key(:revenueType) + expect(event.to_hash).not_to have_key(:productId) + expect(event.to_hash).not_to have_key(:price) + end + end end end