Browse files

Add Notification and NotificationStyle classes; change User to return…

… Notifications from get_pending_notifications; bump version number for gem
  • Loading branch information...
1 parent 0734a1a commit 854b328f5977ffeafcd488ac1ad7cd403e067174 @erebor erebor committed Feb 2, 2012
Showing with 344 additions and 6 deletions.
  1. +1 −1 Gemfile.lock
  2. +1 −0 lib/bunchball.rb
  3. +123 −0 lib/bunchball/nitro/notification.rb
  4. +19 −2 lib/bunchball/nitro/user.rb
  5. +1 −1 lib/bunchball/version.rb
  6. +189 −0 test/test_notification.rb
  7. +10 −2 test/test_user.rb
View
2 Gemfile.lock
@@ -1,7 +1,7 @@
PATH
remote: .
specs:
- bunchball (0.2.1)
+ bunchball (0.2.8)
httparty
GEM
View
1 lib/bunchball.rb
@@ -11,6 +11,7 @@
require 'bunchball/nitro/challenge'
require 'bunchball/nitro/group'
require 'bunchball/nitro/level'
+require 'bunchball/nitro/notification'
require 'bunchball/nitro/response'
require 'bunchball/nitro/rule'
require 'bunchball/nitro/site'
View
123 lib/bunchball/nitro/notification.rb
@@ -0,0 +1,123 @@
+class Bunchball::Nitro::NotificationStyle
+ attr_accessor :html, :name
+ def initialize(response = {})
+ @html = response['html']
+ @name = response['name']
+ end
+end
+
+# This one differs from some of the other wrapper classes (like Challenge) in
+# that we actually have to track matched sets of information from the Response
+# object. So we have to interact more with the Response object that we're going
+# to get in our initializer, instead of expecting it to be a hash as we do in
+# the Challenge and Rule classes.
+class Bunchball::Nitro::Notification
+ attr_accessor :api_response, :style
+
+ def initialize(raw_notification = {}, raw_notification_style = {})
+ raise "Need a valid Hash object (it's a #{raw_notification.class})" unless raw_notification.is_a? Hash
+ @api_response = raw_notification.merge(:_notification_style => raw_notification_style)
+ @style = Bunchball::Nitro::NotificationStyle.new(raw_notification_style)
+ end
+
+ def action
+ @api_response['action']
+ end
+
+ def balance
+ @api_response['balance'].to_i
+ end
+
+ def challenge
+ @api_response['challenge']
+ end
+
+ def do_share
+ @api_response['doShare']
+ end
+
+ def has_trophy?
+ @api_response['challengeTrophyFullUrl'] || @api_response['challengeTrophyThumbUrl']
+ end
+
+ def lifetime_balance
+ @api_response['lifetimeBalance'].to_i
+ end
+
+ def name
+ @api_response['name']
+ end
+
+ def newsfeed
+ @api_response['newsfeed']
+ end
+
+ def notification_settings
+ @api_response['notificationSettings']
+ end
+ # We really want to call it like this, but for least-surprise, we'll also have
+ # the more closely-matches-the-API name
+ alias settings notification_settings
+
+ def point_category
+ @api_response['pointCategory']
+ end
+
+ def point_category_icon_url
+ @api_response['pointCategoryIconUrl']
+ end
+
+ def point_category_limit
+ @api_response['pointCategoryLimit'].to_i
+ end
+
+ def point_category_short
+ @api_response['pointCategoryShort']
+ end
+
+ def points
+ @api_response['points'].to_i
+ end
+
+ def style_name
+ @api_response['styleName']
+ end
+
+ def timestamp
+ Time.at(@api_response['timestamp'].to_i) if @api_response['timestamp']
+ end
+
+ def trophy_url
+ @api_response['challengeTrophyFullUrl']
+ end
+ # We really want to call it like this, but for least-surprise, we'll also have
+ # the more closely-matches-the-API name
+ alias full_url trophy_url
+
+ def trophy_thumb_url
+ @api_response['challengeTrophyThumbUrl']
+ end
+ # We really want to call it like this, but for least-surprise, we'll also have
+ # the more closely-matches-the-API name
+ alias thumb_url trophy_thumb_url
+
+ def updated
+ Time.at(@api_response['updated'].to_i) if @api_response['updated']
+ end
+
+ def user
+ Bunchball::Nitro::User.new(@api_response['userId'])
+ end
+
+ def user_id
+ @api_response['userId']
+ end
+
+ def value
+ @api_response['value'].to_i
+ end
+
+ def version
+ @api_response['version'].to_i
+ end
+end
View
21 lib/bunchball/nitro/user.rb
@@ -370,8 +370,25 @@ def get_owned_items(params = {})
def self.get_pending_notifications(user_id, params = {})
response = post("user.getPendingNotifications", {:userId => user_id}.merge(params))
- # Two top-level keys here need returning, so we'll just return the whole thing.
- Response.new response
+ response = Response.new(response)
+ payload = []
+
+ # Two top-level keys here need processing, 'notifications' and 'notificationStyles'
+ # However, if the first one is just True, then there were no pending notifications,
+ # so we just return the empty array as the payload.
+
+ unless response.payload['notifications'] == true # actual true, not a 'truthy' value
+
+ # Stick the styles into an array in case they're not (if there was only one)
+ notification_styles = [response.payload['notificationStyles']['NotificationStyle']].flatten.compact
+
+ [response.payload['notifications']['Notification']].flatten.compact.each_with_index do |notification, index|
+ n = Notification.new(notification, notification_styles[index])
+ payload << n
+ end
+ end
+ response.payload = payload
+ response
end
def get_pending_notifications(params = {})
View
2 lib/bunchball/version.rb
@@ -1,3 +1,3 @@
module Bunchball
- VERSION = '0.2.7'
+ VERSION = '0.2.8'
end
View
189 test/test_notification.rb
@@ -0,0 +1,189 @@
+require 'test_helper'
+
+class TestNotification < Test::Unit::TestCase
+
+ def sample_notification_style
+ {
+ "html" => "{{notification_setting_Message|Congratulations! You just completed the {nitro_challenge} challenge and earned {nitro_points} {nitro_pointCategory}!|string}}",
+ "name" => "Mobile Trophy Awarded Style"
+ }
+ end
+
+ def sample_notification
+ {
+ "action" => "TEST_MOBILE_NOTIFICATION_FLOW",
+ "balance" => "1227",
+ "challenge" => "Test Mobile Notification Flow",
+ "challengeTrophyFullUrl" => "http://www.collectiblebadges.com/media/large_crime_scene_investigator_badge_gold.jpg",
+ "challengeTrophyThumbUrl" => "http://www.collectiblebadges.com/media/large_crime_scene_investigator_badge_gold.jpg",
+ "doShare" => "0",
+ "lifetimeBalance" => "1352",
+ "name" => "Mobile Trophy Challenge Completed",
+ "newsfeed" => "null",
+ "pointCategory" => "Points",
+ "pointCategoryIconUrl" => "",
+ "pointCategoryLimit" => "25",
+ "pointCategoryShort" => "Pts",
+ "points" => "25",
+ "styleName" => "Mobile Trophy Awarded Style",
+ "timestamp" => "1328207836",
+ "updated" => "1328138000",
+ "userId" => "melinda@newsit.net",
+ "value" => "0",
+ "version" => "0",
+ "notificationSettings" => {
+ "NotificationSetting" => [
+ { "name" => "Delay (secs)",
+ "value" => "0"
+ },
+ { "name" => "Duration (secs)",
+ "value" => "5"
+ },
+ { "name" => "Frequency",
+ "value" => "Unlimited"
+ },
+ { "name" => "Corner",
+ "value" => "Bottom Right"
+ },
+ { "name" => "Direction",
+ "value" => "Vertical"
+ },
+ { "name" => "Message",
+ "value" => "Congratulations! You just completed the {nitro_challenge} challenge and earned {nitro_points} {nitro_pointCategory}!"
+ }
+ ]
+ }
+ }
+ end
+
+ def make_notification(notify = sample_notification, notify_style = sample_notification_style)
+ Bunchball::Nitro::Notification.new(notify, notify_style)
+ end
+
+ def test_action
+ notification = make_notification(sample_notification.merge('action' => 'Wobbly'))
+ assert_equal 'Wobbly', notification.action
+ end
+
+ def test_balance
+ notification = make_notification(sample_notification.merge('balance' => '75'))
+ assert_equal notification.balance, 75
+ end
+
+ def test_challenge
+ notification = make_notification(sample_notification.merge('challenge' => 'Wobbly'))
+ assert_equal 'Wobbly', notification.challenge
+ end
+
+ def test_do_share
+ notification = make_notification(sample_notification.merge('doShare' => 'Wobbly'))
+ assert_equal 'Wobbly', notification.do_share
+ end
+
+ def test_has_trophy?
+ notification = make_notification(sample_notification.merge('challengeTrophyThumbUrl' => 'foo'))
+ assert notification.has_trophy?
+ notification = make_notification(sample_notification.merge('challengeTrophyFullUrl' => 'foo'))
+ assert notification.has_trophy?
+ end
+
+ def test_initialize
+ notification = make_notification
+ assert_equal notification.class, Bunchball::Nitro::Notification
+ end
+
+ def test_lifetime_balance
+ notification = make_notification(sample_notification.merge('lifetimeBalance' => '75'))
+ assert_equal notification.lifetime_balance, 75
+ end
+
+ def test_name
+ notification = make_notification(sample_notification.merge('name' => 'Wobbly'))
+ assert_equal 'Wobbly', notification.name
+ end
+
+ def test_newsfeed
+ notification = make_notification(sample_notification.merge('newsfeed' => 'Wobbly'))
+ assert_equal 'Wobbly', notification.newsfeed
+ end
+
+ def test_notification_settings
+ notification = make_notification(sample_notification.merge('notificationSettings' => 'Wobbly'))
+ assert_equal 'Wobbly', notification.notification_settings
+ end
+
+ def test_point_category
+ notification = make_notification(sample_notification.merge('pointCategory' => 'Wobbly'))
+ assert_equal 'Wobbly', notification.point_category
+ end
+
+ def test_point_category_icon_url
+ notification = make_notification(sample_notification.merge('pointCategoryIconUrl' => 'foo'))
+ assert_equal 'foo', notification.point_category_icon_url
+ end
+
+ def test_point_category_limit
+ notification = make_notification(sample_notification.merge('pointCategoryLimit' => '75'))
+ assert_equal notification.point_category_limit, 75
+ end
+
+ def test_point_category_short
+ notification = make_notification(sample_notification.merge('pointCategoryShort' => 'Wobbly'))
+ assert_equal 'Wobbly', notification.point_category_short
+ end
+
+ def test_points
+ notification = make_notification(sample_notification.merge('points' => '75'))
+ assert_equal notification.points, 75
+ end
+
+ def test_style_name
+ notification = make_notification(sample_notification.merge('styleName' => 'Wobbly'))
+ assert_equal 'Wobbly', notification.style_name
+ end
+
+ def test_timestamp
+ test_time = Time.now.to_i - 3600
+ notification = make_notification(sample_notification.merge('timestamp' => test_time))
+ assert notification.timestamp.is_a? Time
+ assert_equal Time.at(test_time), notification.timestamp
+ end
+
+ def test_trophy_url
+ notification = make_notification(sample_notification.merge('challengeTrophyFullUrl' => 'foo'))
+ assert_equal 'foo', notification.trophy_url
+ end
+
+ def test_trophy_thumb_url
+ notification = make_notification(sample_notification.merge('challengeTrophyThumbUrl' => 'foo'))
+ assert_equal 'foo', notification.trophy_thumb_url
+ end
+
+ def test_updated
+ test_time = Time.now.to_i - 3600
+ notification = make_notification(sample_notification.merge('updated' => test_time))
+ assert notification.updated.is_a? Time
+ assert_equal Time.at(test_time), notification.updated
+ end
+
+ def test_user
+ notification = make_notification(sample_notification.merge('userId' => 'foo'))
+ assert notification.user.is_a? Bunchball::Nitro::User
+ assert_equal 'foo', notification.user.user_id
+ end
+
+ def test_user_id
+ notification = make_notification(sample_notification.merge('userId' => 'foo'))
+ assert_equal 'foo', notification.user_id
+ end
+
+ def test_value
+ notification = make_notification(sample_notification.merge('value' => '75'))
+ assert_equal notification.value, 75
+ end
+
+ def test_version
+ notification = make_notification(sample_notification.merge('version' => '75'))
+ assert_equal notification.version, 75
+ end
+end
View
12 test/test_user.rb
@@ -665,12 +665,20 @@ def test_get_owned_items_instance
def test_get_pending_notifications
params = {:userId => 'wiggly'}
- return_value = {'Nitro' => 'foo' }
+ return_value = {'Nitro' => {'res' => 'ok',
+ 'notifications' =>
+ {'Notification' => {'name' => 'A Notification 1', 'points' => '25' }},
+ 'notificationStyles' =>
+ {'NotificationStyle' => {'name' => 'A Notification Style 1', 'html' => 'foo' }}
+ }
+ }
Bunchball::Nitro::User.expects(:post).with("user.getPendingNotifications", params).returns(return_value)
response = Bunchball::Nitro::User.get_pending_notifications('wiggly')
- assert_equal response.payload, 'foo'
+ assert response.payload.first.is_a? Bunchball::Nitro::Notification
+ assert_equal response.payload.first.name, 'A Notification 1'
+ assert_equal response.payload.first.style.name, 'A Notification Style 1'
end
def test_get_pending_notifications_instance

0 comments on commit 854b328

Please sign in to comment.