Skip to content

Commit

Permalink
[TOOLSLIBS-392] Attribute Audience Selectors (#168)
Browse files Browse the repository at this point in the history
* adds date_attribute audience selector

* adds date_attribute tests

* missing black formatting

* adds text_attribute selector

* adds text_attribute tests

* adds check for text type

* adds number_attribute

* adds number attribute

* adds nubmer attribute tests

* adds proper typing to date_attribute

* adds to changelog

* rm datetime check
  • Loading branch information
aschuman0 authored Nov 3, 2021
1 parent 2dc79d9 commit 001062d
Show file tree
Hide file tree
Showing 7 changed files with 389 additions and 137 deletions.
1 change: 1 addition & 0 deletions CHANGELOG
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

- Adds iOS platform options for: interruption_level, relevance_score, and target_content_id
- Adds amazon platform options for: notification_tag, notification_channel, icon, icon_color
- Adds audience selectors for date_attribute, text_attribute, and number_attribute
- Adds attributes, device_attributes, named_user_id, commercial_opted_in, commercial_opted_out, transactional_opted_in, transactional_opted_out to channel look up and listing.
- Adds support for setting attributes on channel ids and named user ids
- Adds support for removing attributes from channel ids and named user ids
Expand Down
164 changes: 159 additions & 5 deletions tests/push/test_audience.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import datetime
import unittest

import urbanairship as ua
Expand Down Expand Up @@ -26,11 +27,7 @@ def test_basic_selectors(self):
"074e84a2-9ed9-4eee-9ca4-cc597bfdbef3",
{"open_channel": "074e84a2-9ed9-4eee-9ca4-cc597bfdbef3"},
),
(
ua.device_token,
"f" * 64,
{"device_token": "F" * 64},
),
(ua.device_token, "f" * 64, {"device_token": "F" * 64}),
(ua.device_token, "0" * 64, {"device_token": "0" * 64}),
(
ua.apid,
Expand Down Expand Up @@ -118,3 +115,160 @@ def test_location_selector(self):
self.assertRaises(ValueError, ua.location)
self.assertRaises(ValueError, ua.location, alias=1, id=1)
self.assertRaises(ValueError, ua.location, date=None, id="foobar")


class TestAttributeSelectors(unittest.TestCase):
def test_date_incorrect_operator_raises(self):
with self.assertRaises(ValueError) as err_ctx:
ua.date_attribute(attribute="test_attribute", operator="the_way_we_wont")

self.assertEqual(
err_ctx.message,
"operator must be one of: 'is_empty', 'before', 'after', 'range', 'equals'",
)

def test_date_is_empty(self):
selector = ua.date_attribute(attribute="test_attribute", operator="is_empty")

self.assertEqual(
selector, {"attribute": "test_attribute", "operator": "is_empty"}
)

# testing exception raising only on before. after and equals use same codepath
def test_date_before_no_value_raises(self):
with self.assertRaises(ValueError) as err_ctx:
ua.date_attribute(
attribute="test_attribute", operator="before", precision="years"
)

self.assertEqual(
err_ctx.message,
"value must be included when using the 'before' operator",
)

def test_date_before_no_precision_raises(self):
with self.assertRaises(ValueError) as err_ctx:
ua.date_attribute(
attribute="test_attribute",
operator="before",
value="2021-11-03 12:00:00",
)

self.assertEqual(
err_ctx.message,
"precision must be included when using the 'before' operator",
)

def test_date_before(self):
selector = ua.date_attribute(
attribute="test_attribute",
operator="before",
value="2021-11-03 12:00:00",
precision="years",
)

self.assertEqual(
selector,
{
"attribute": "test_attribute",
"operator": "before",
"value": "2021-11-03 12:00:00",
"precision": "years",
},
)

def test_date_after(self):
selector = ua.date_attribute(
attribute="test_attribute",
operator="after",
value="2021-11-03 12:00:00",
precision="years",
)

self.assertEqual(
selector,
{
"attribute": "test_attribute",
"operator": "after",
"value": "2021-11-03 12:00:00",
"precision": "years",
},
)

def test_date_equals(self):
selector = ua.date_attribute(
attribute="test_attribute",
operator="equals",
value="2021-11-03 12:00:00",
precision="years",
)

self.assertEqual(
selector,
{
"attribute": "test_attribute",
"operator": "equals",
"value": "2021-11-03 12:00:00",
"precision": "years",
},
)

def test_text(self):
selector = ua.text_attribute(
attribute="test_attribute", operator="equals", value="test_value"
)

self.assertEqual(
selector,
{
"attribute": "test_attribute",
"operator": "equals",
"value": "test_value",
},
)

def test_text_incorrect_operator_raises(self):
with self.assertRaises(ValueError) as err_ctx:
ua.text_attribute(
attribute="test_attribute", operator="am_180", value="test_value"
)

self.assertEqual(
err_ctx.message,
"operator must be one of 'equals', 'contains', 'less', 'greater', 'is_empty'",
)

def test_text_incorrect_value_type_raises(self):
with self.assertRaises(ValueError) as err_ctx:
ua.text_attribute(attribute="test_attribute", operator="am_180", value=2001)

self.assertEqual(err_ctx.message, "value must be a string")

def test_number(self):
selector = ua.number_attribute(
attribute="test_attribute", operator="equals", value=100
)

self.assertEqual(
selector,
{"attribute": "test_attribute", "operator": "equals", "value": 100},
)

def test_number_incorrect_operator_raises(self):
with self.assertRaises(ValueError) as err_ctx:
ua.number_attribute(
attribute="test_attribute", operator="am_180", value="test_value"
)

self.assertEqual(
err_ctx.message,
"operator must be one of 'equals', 'contains', 'less', 'greater', 'is_empty'",
)

def test_number_incorrect_value_type_raises(self):
with self.assertRaises(ValueError) as err_ctx:
ua.number_attribute(
attribute="test_attribute", operator="equals", value="ive_got_it"
)

self.assertEqual(err_ctx.message, "value must be an integer")
32 changes: 10 additions & 22 deletions tests/push/test_push.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@

import mock
import requests

import urbanairship as ua
from tests import TEST_KEY, TEST_SECRET

Expand Down Expand Up @@ -350,10 +349,7 @@ def test_sms_overrides(self):
p.audience = ua.all_
p.notification = ua.notification(
alert="top level alert",
sms=ua.sms(
alert="sms override alert",
expiry="2018-04-01T12:00:00",
),
sms=ua.sms(alert="sms override alert", expiry="2018-04-01T12:00:00"),
)
p.device_types = ua.device_types("sms")

Expand Down Expand Up @@ -459,10 +455,7 @@ def test_standard_ios_opts(self):
p.audience = ua.all_
p.notification = ua.notification(
alert="Top level alert",
ios=ua.ios(
alert="iOS override alert",
sound="cat.caf",
),
ios=ua.ios(alert="iOS override alert", sound="cat.caf"),
)
p.device_types = ua.device_types("ios")

Expand Down Expand Up @@ -539,7 +532,7 @@ def test_ios_overrides(self):
"collapse_id": "nugent sand",
"interruption_level": "critical",
"relevance_score": 0.75,
"target_content_id": "big day coming"
"target_content_id": "big day coming",
}
},
"device_types": "ios",
Expand Down Expand Up @@ -1011,18 +1004,15 @@ def test_amazon_overrides(self):
"icon": "icon.img",
"icon_color": "#1234ff",
}
}
}
},
},
)

def test_standard_amazon_push(self):
p = ua.Push(None)
p.audience = ua.all_
p.notification = ua.notification(
alert="top level alert",
amazon=ua.amazon(
alert="amazon override alert"
)
alert="top level alert", amazon=ua.amazon(alert="amazon override alert")
)
p.device_types = ua.device_types("amazon")

Expand All @@ -1033,9 +1023,7 @@ def test_standard_amazon_push(self):
"device_types": ["amazon"],
"notification": {
"alert": "top level alert",
"amazon": {
"alert": "amazon override alert"
}
}
}
)
"amazon": {"alert": "amazon override alert"},
},
},
)
Loading

0 comments on commit 001062d

Please sign in to comment.