Skip to content

Commit

Permalink
Merge pull request #95 from urbanairship/TOOLSLIBS-309-b
Browse files Browse the repository at this point in the history
Merge in Named user attributes branch from OLIOEX, prep for release
  • Loading branch information
pdxmele authored Jul 2, 2021
2 parents 039c4f3 + faa4540 commit d5f6431
Show file tree
Hide file tree
Showing 16 changed files with 309 additions and 18 deletions.
4 changes: 2 additions & 2 deletions .github/PULL_REQUEST_TEMPLATE.md
Original file line number Diff line number Diff line change
Expand Up @@ -15,8 +15,8 @@ Please include link to open issue if applicable.

* I've tested for Ruby versions:

- [ ] 2.2.5
- [ ] 2.3.1
- [ ] 2.6.7
- [ ] 2.7.2

### Airship Contribution Agreement
[Link here](https://docs.google.com/forms/d/e/1FAIpQLScErfiz-fXSPpVZ9r8Di2Tr2xDFxt5MgzUel0__9vqUgvko7Q/viewform)
Expand Down
3 changes: 1 addition & 2 deletions .travis.yml
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
language: ruby
rvm:
- 2.2.5
- 2.3.1
- 2.6.7
- 2.7.2
9 changes: 9 additions & 0 deletions CHANGELOG
Original file line number Diff line number Diff line change
@@ -1,3 +1,12 @@
--------------------
8.0.0
--------------------
- Updates officially supported versions to 2.6.7 and 2.7.2
- Fixes headers to reduce warning messages
- Fixes for multiple mis-set named user urls
- Fix to automatically convert an integer named user to a string so it can be successfully submitted
- Adds attribute support for named users

--------------------
7.0.0
--------------------
Expand Down
8 changes: 4 additions & 4 deletions README.rst
Original file line number Diff line number Diff line change
Expand Up @@ -14,16 +14,16 @@ Requirements

We officially support the following Ruby versions::

2.2.5
2.3.1
2.6.7
2.7.2

Newer versions should work as well.
Newer 2.x versions should work as well.


Functionality
=============

Version 5.0 is a major upgrade, as some features have been removed that were present in earlier versions. A more detailed list of changes can be found in the CHANGELOG.
Version 8.0 is a major upgrade, as we have changed the tested/supported versions of Ruby. A more detailed list of changes can be found in the CHANGELOG.


Questions
Expand Down
21 changes: 21 additions & 0 deletions docs/attributes.rst
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,27 @@ The following will set an attribute for a given channel ID.

This should return a 200 response

Set or Remove Attributes for a Named User
-----------------------------------------

The following example shows you how to set and remove attributes on a given named user.

.. code-block:: ruby
require 'urbanairship'
airship = Urbanairship::Client.new(key: 'application_key', secret: 'master_secret')
named_user = Urbanairship::NamedUser.new(client: airship)
named_user.named_user_id = 'named_user'
named_user.update_attributes(attributes: [
{ action: 'set', key: 'first_name', value: 'Firstname' },
{ action: 'remove', key: 'nickname' },
{ action: 'set', key: 'last_name', value: 'Lastname', timestamp: Time.now.utc }
])
.. note::

Timestamp is optional, if missing it will default to 'now'

Send Push to Audience with Attribute Specifications
---------------------------------------------------

Expand Down
22 changes: 22 additions & 0 deletions docs/named_user.rst
Original file line number Diff line number Diff line change
Expand Up @@ -100,3 +100,25 @@ see `the API documentation

A single request may contain an add or remove field, both, or a single set
field.

Attributes
----------

Set or remove attributes on a named user. For more information, see `the API documentation
https://docs.airship.com/api/ua/#operation-api-named_users-named_user_id-attributes-post>`__

.. code-block:: ruby
require 'urbanairship'
airship = Urbanairship::Client.new(key: 'application_key', secret: 'master_secret')
named_user = Urbanairship::NamedUser.new(client: airship)
named_user.named_user_id = 'named_user'
named_user.update_attributes(attributes: [
{ action: 'set', key: 'first_name', value: 'Firstname' },
{ action: 'remove', key: 'nickname' },
{ action: 'set', key: 'last_name', value: 'Lastname', timestamp: Time.now.utc }
])
.. note::

Timestamp is optional, if missing it will default to 'now'.
1 change: 1 addition & 0 deletions lib/urbanairship.rb
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@
require 'urbanairship/devices/mms_notification'
require 'urbanairship/devices/create_and_send'
require 'urbanairship/devices/attribute'
require 'urbanairship/devices/attributes'
require 'urbanairship/client'
require 'urbanairship/common'
require 'urbanairship/configuration'
Expand Down
2 changes: 2 additions & 0 deletions lib/urbanairship/common.rb
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,8 @@
module Urbanairship
# Features mixed in to all classes
module Common
CONTENT_TYPE = 'application/json'

def apid_path(path='')
"/apids/#{path}"
end
Expand Down
53 changes: 53 additions & 0 deletions lib/urbanairship/devices/attributes.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@

module Urbanairship
module Devices
class Attributes

SET = 'set'
REMOVE = 'remove'

def initialize(attributes)
@attributes = attributes
end

def payload
@payload ||= { attributes: attributes_list }
end

private

def attributes_list
@attributes.map{ |attribute| attribute_payload(attribute) }
end

def attribute_payload(attribute)
if REMOVE == attribute[:action]
remove_payload(attribute)
else
set_payload(attribute)
end
end

def set_payload(attribute)
{
action: SET,
key: attribute[:key],
value: attribute[:value],
timestamp: (attribute[:timestamp] || timestamp).iso8601,
}
end

def remove_payload(attribute)
{
action: REMOVE,
key: attribute[:key],
timestamp: (attribute[:timestamp] || timestamp).iso8601,
}
end

def timestamp
@timestamp ||= Time.now.utc
end
end
end
end
26 changes: 18 additions & 8 deletions lib/urbanairship/devices/named_user.rb
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
require 'urbanairship'


module Urbanairship
module Devices
class NamedUser
Expand All @@ -13,6 +12,17 @@ def initialize(client: required('client'))
@named_user_id = nil
end

def update_attributes(attributes: required('attributes'))
response = @client.send_request(
method: 'POST',
body: Urbanairship::Attributes.new(attributes).payload.to_json,
path: named_users_path("#{@named_user_id}/attributes"),
content_type: CONTENT_TYPE,
)
logger.info { "Updated attributes for named_user #{@named_user_id}" }
response
end

def associate(channel_id: required('channel_id'), device_type: nil)
fail ArgumentError,
'named_user_id is required for association' if @named_user_id.nil?
Expand All @@ -26,7 +36,7 @@ def associate(channel_id: required('channel_id'), device_type: nil)
method: 'POST',
body: JSON.dump(payload),
path: named_users_path('associate'),
content_type: 'application/json'
content_type: CONTENT_TYPE
)
logger.info { "Associated channel_id #{channel_id} with named_user #{@named_user_id}" }
response
Expand All @@ -40,8 +50,8 @@ def disassociate(channel_id: required('channel_id'), device_type: nil)
response = @client.send_request(
method: 'POST',
body: JSON.dump(payload),
path: named_users_path('/disassociate'),
content_type: 'application/json'
path: named_users_path('disassociate'),
content_type: CONTENT_TYPE
)
logger.info { "Dissociated channel_id #{channel_id}" }
response
Expand All @@ -51,8 +61,8 @@ def lookup
fail ArgumentError,
'named_user_id is required for lookup' if @named_user_id.nil?
response = @client.send_request(
method: 'GET',
path: named_users_path('?id=' + @named_user_id),
method: 'GET',
path: named_users_path('?id=' + @named_user_id),
)
logger.info { "Retrieved information on named_user_id #{@named_user_id}" }
response
Expand Down Expand Up @@ -101,8 +111,8 @@ def uninstall
response = @client.send_request(
method: 'POST',
body: JSON.dump(payload),
path: named_users_path('/uninstall'),
content_type: 'application/json'
path: named_users_path('uninstall'),
content_type: CONTENT_TYPE
)
logger.info { "Uninstalled named_user_ids #{@named_user_ids} " }
response
Expand Down
2 changes: 1 addition & 1 deletion lib/urbanairship/version.rb
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
module Urbanairship
VERSION = '7.0.0'
VERSION = '8.0.0'
end
4 changes: 4 additions & 0 deletions spec/lib/urbanairship/common_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,10 @@
require 'urbanairship'

describe Urbanairship::Common do
it 'defines CONTENT_TYPE' do
expect(described_class::CONTENT_TYPE).to eq 'application/json'
end

it 'has a PUSH_URL' do
expect(Urbanairship.push_path).not_to be nil
end
Expand Down
128 changes: 128 additions & 0 deletions spec/lib/urbanairship/devices/attributes_spec.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,128 @@
require 'spec_helper'
require 'urbanairship'
require 'urbanairship/devices/attributes'

describe Urbanairship::Devices::Attributes do
let(:key_1) { 'first_name' }
let(:value_1) { 'Airship' }
let(:key_2) { 'last_name' }
let(:value_2) { 'API' }
let(:timestamp) { Time.now.utc - 3600 }

let(:attributes) do
[
{ key: key_1, value: value_1, action: described_class::SET, timestamp: timestamp },
]
end
let(:expected) do
{
attributes: [
{
key: key_1,
value: value_1,
action: described_class::SET,
timestamp: timestamp.iso8601,
},
],
}
end

before { Timecop.freeze(Time.now.utc) }
after { Timecop.return }

describe 'Payload' do
let(:payload) { described_class.new(attributes).payload }

context 'Action type is not set' do
let(:attributes) do
[
{ key: key_1, value: value_1, timestamp: timestamp },
]
end

it 'defaults to `set` action' do
puts timestamp.iso8601
expect(payload).to eq expected
end
end

describe 'Set action' do
it 'defaults to `set` action' do
expect(payload).to eq expected
end
end

context 'Timestamp not provided' do
let(:timestamp) { nil }
let(:expected) do
{
attributes: [
{
key: key_1,
value: value_1,
action: described_class::SET,
timestamp: Time.now.utc.iso8601,
},
],
}
end

it 'uses expected provided timestamp' do
expect(payload).to eq expected
end
end

describe 'Remove action' do
let(:attributes) do
[
{ key: key_1, action: described_class::REMOVE, timestamp: timestamp }
]
end
let(:expected) do
{
attributes: [
{
key: key_1,
action: described_class::REMOVE,
timestamp: timestamp.iso8601,
},
],
}
end

it 'generates expected payload' do
expect(payload).to eq expected
end
end

describe 'Loops over multiple records' do
let(:attributes) do
[
{ key: key_1, action: described_class::REMOVE },
{ key: key_2, value: value_2 }
]
end
let(:expected) do
{
attributes: [
{
key: key_1,
action: described_class::REMOVE,
timestamp: Time.now.utc.iso8601,
},
{
key: key_2,
value: value_2,
action: described_class::SET,
timestamp: Time.now.utc.iso8601,
},
],
}
end

it 'generates expected payload' do
expect(payload).to eq expected
end
end
end
end
Loading

0 comments on commit d5f6431

Please sign in to comment.