ruby-iactionable 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (49) hide show
  1. data/.gitignore +4 -0
  2. data/.rvmrc +3 -0
  3. data/CHANGELOG.md +5 -0
  4. data/Gemfile +4 -0
  5. data/Gemfile.lock +43 -0
  6. data/README.md +49 -0
  7. data/Rakefile +1 -0
  8. data/lib/iactionable/api.rb +170 -0
  9. data/lib/iactionable/connection.rb +114 -0
  10. data/lib/iactionable/error.rb +17 -0
  11. data/lib/iactionable/objects/achievement.rb +29 -0
  12. data/lib/iactionable/objects/awardable.rb +50 -0
  13. data/lib/iactionable/objects/challenge.rb +27 -0
  14. data/lib/iactionable/objects/goal.rb +30 -0
  15. data/lib/iactionable/objects/i_actionable_object.rb +36 -0
  16. data/lib/iactionable/objects/identifier.rb +17 -0
  17. data/lib/iactionable/objects/leaderboard.rb +15 -0
  18. data/lib/iactionable/objects/leaderboard_report.rb +30 -0
  19. data/lib/iactionable/objects/level.rb +24 -0
  20. data/lib/iactionable/objects/level_type.rb +15 -0
  21. data/lib/iactionable/objects/point_type.rb +15 -0
  22. data/lib/iactionable/objects/profile_achievements.rb +20 -0
  23. data/lib/iactionable/objects/profile_challenges.rb +20 -0
  24. data/lib/iactionable/objects/profile_goals.rb +20 -0
  25. data/lib/iactionable/objects/profile_level.rb +20 -0
  26. data/lib/iactionable/objects/profile_notifications.rb +29 -0
  27. data/lib/iactionable/objects/profile_points.rb +29 -0
  28. data/lib/iactionable/objects/profile_summary.rb +32 -0
  29. data/lib/iactionable/objects/progress.rb +46 -0
  30. data/lib/iactionable/objects.rb +27 -0
  31. data/lib/iactionable/settings.rb +30 -0
  32. data/lib/iactionable/version.rb +3 -0
  33. data/lib/iactionable.rb +9 -0
  34. data/ruby_iactionable.gemspec +28 -0
  35. data/spec/api/get_achievements_api_response_spec.rb +46 -0
  36. data/spec/api/get_challenges_api_response_spec.rb +42 -0
  37. data/spec/api/get_goals_api_response_spec.rb +46 -0
  38. data/spec/api/get_leaderboard_api_response_spec.rb +76 -0
  39. data/spec/api/get_profile_achievements_api_response_spec.rb +99 -0
  40. data/spec/api/get_profile_api_response_spec.rb +103 -0
  41. data/spec/api/get_profile_challenges_api_response_spec.rb +85 -0
  42. data/spec/api/get_profile_goals_api_response_spec.rb +89 -0
  43. data/spec/api/get_profile_notifications_api_response_spec.rb +75 -0
  44. data/spec/api/get_profile_points_api_response_spec.rb +67 -0
  45. data/spec/api_spec.rb +314 -0
  46. data/spec/connection_spec.rb +111 -0
  47. data/spec/settings_spec.rb +52 -0
  48. data/spec/spec_helper.rb +1 -0
  49. metadata +163 -0
@@ -0,0 +1,15 @@
1
+ module IActionable
2
+ module Objects
3
+ class LevelType < IActionableObject
4
+ attr_accessor :key
5
+ attr_accessor :name
6
+
7
+ def to_hash
8
+ {
9
+ "Key" => @key,
10
+ "Name" => @name
11
+ }
12
+ end
13
+ end
14
+ end
15
+ end
@@ -0,0 +1,15 @@
1
+ module IActionable
2
+ module Objects
3
+ class PointType < IActionableObject
4
+ attr_accessor :key
5
+ attr_accessor :name
6
+
7
+ def to_hash
8
+ {
9
+ "Key" => @key,
10
+ "Name" => @name
11
+ }
12
+ end
13
+ end
14
+ end
15
+ end
@@ -0,0 +1,20 @@
1
+ module IActionable
2
+ module Objects
3
+ class ProfileAchievements < IActionableObject
4
+ attr_accessor :available
5
+ attr_accessor :completed
6
+
7
+ def initialize(key_values={})
8
+ @available = extract_many_as(key_values, "Available", IActionable::Objects::Achievement)
9
+ @completed = extract_many_as(key_values, "Completed", IActionable::Objects::Achievement)
10
+ end
11
+
12
+ def to_hash
13
+ {
14
+ "Available" => @available.map{|achievement| achievement.to_hash},
15
+ "Completed" => @completed.map{|achievement| achievement.to_hash}
16
+ }
17
+ end
18
+ end
19
+ end
20
+ end
@@ -0,0 +1,20 @@
1
+ module IActionable
2
+ module Objects
3
+ class ProfileChallenges < IActionableObject
4
+ attr_accessor :available
5
+ attr_accessor :completed
6
+
7
+ def initialize(key_values={})
8
+ @available = extract_many_as(key_values, "Available", IActionable::Objects::Challenge)
9
+ @completed = extract_many_as(key_values, "Completed", IActionable::Objects::Challenge)
10
+ end
11
+
12
+ def to_hash
13
+ {
14
+ "Available" => @available.map{|challenge| challenge.to_hash},
15
+ "Completed" => @completed.map{|challenge| challenge.to_hash}
16
+ }
17
+ end
18
+ end
19
+ end
20
+ end
@@ -0,0 +1,20 @@
1
+ module IActionable
2
+ module Objects
3
+ class ProfileGoals < IActionableObject
4
+ attr_accessor :available
5
+ attr_accessor :completed
6
+
7
+ def initialize(key_values={})
8
+ @available = extract_many_as(key_values, "Available", IActionable::Objects::Goal)
9
+ @completed = extract_many_as(key_values, "Completed", IActionable::Objects::Goal)
10
+ end
11
+
12
+ def to_hash
13
+ {
14
+ "Available" => @available.map{|goal| goal.to_hash},
15
+ "Completed" => @completed.map{|goal| goal.to_hash}
16
+ }
17
+ end
18
+ end
19
+ end
20
+ end
@@ -0,0 +1,20 @@
1
+ module IActionable
2
+ module Objects
3
+ class ProfileLevel < IActionableObject
4
+ attr_accessor :current
5
+ attr_accessor :next
6
+
7
+ def initialize(key_values={})
8
+ @current = IActionable::Objects::Level.new(key_values.delete("Current")) unless key_values["Current"].blank?
9
+ @next = IActionable::Objects::Level.new(key_values.delete("Next")) unless key_values["Next"].blank?
10
+ end
11
+
12
+ def to_hash
13
+ {
14
+ "Current" => @current.to_hash,
15
+ "Next" => @next.to_hash
16
+ }
17
+ end
18
+ end
19
+ end
20
+ end
@@ -0,0 +1,29 @@
1
+ module IActionable
2
+ module Objects
3
+ class ProfileNotifications < IActionableObject
4
+ attr_accessor :achievements
5
+ attr_accessor :challenges
6
+ attr_accessor :goals
7
+ attr_accessor :levels
8
+ attr_accessor :points
9
+
10
+ def initialize(key_values={})
11
+ @achievements = IActionable::Objects::ProfileAchievements.new(key_values.delete("Achievements"))
12
+ @challenges = IActionable::Objects::ProfileChallenges.new(key_values.delete("Challenges"))
13
+ @goals = IActionable::Objects::ProfileGoals.new(key_values.delete("Goals"))
14
+ @levels = extract_many_as(key_values, "Levels", IActionable::Objects::Level)
15
+ @points = extract_many_as(key_values, "Points", IActionable::Objects::ProfilePoints)
16
+ end
17
+
18
+ def to_hash
19
+ {
20
+ "Achievements" => @achievements.to_hash,
21
+ "Challenges" => @challenges.to_hash,
22
+ "Goals" => @goals.to_hash,
23
+ "Levels" => @levels.map{|level| level.to_hash},
24
+ "Points" => @points.map{|point| point.to_hash}
25
+ }
26
+ end
27
+ end
28
+ end
29
+ end
@@ -0,0 +1,29 @@
1
+ module IActionable
2
+ module Objects
3
+ class ProfilePoints < IActionableObject
4
+ attr_accessor :level # not always present
5
+ attr_accessor :point_type
6
+ attr_accessor :points
7
+ attr_accessor :reason # not always present
8
+
9
+ def initialize(key_values={})
10
+ levels = key_values.delete("Level")
11
+ @level = IActionable::Objects::ProfileLevel.new(levels) unless levels.nil?
12
+ @point_type = IActionable::Objects::PointType.new(key_values.delete("PointType"))
13
+ super(key_values)
14
+ end
15
+
16
+ def to_hash
17
+ hash = {
18
+ "Level" => @level.nil? ? nil : @level.to_hash,
19
+ "PointType" => @point_type.to_hash,
20
+ "Points" => @points,
21
+ "Reason" => @reason
22
+ }
23
+ hash.delete "Level" if @level.nil?
24
+ hash.delete "Reason" if @reason.nil?
25
+ hash
26
+ end
27
+ end
28
+ end
29
+ end
@@ -0,0 +1,32 @@
1
+ module IActionable
2
+ module Objects
3
+ class ProfileSummary < IActionableObject
4
+ attr_accessor :display_name
5
+ attr_accessor :identifiers
6
+ attr_accessor :points
7
+ attr_accessor :recent_achievements # not always present
8
+ attr_accessor :rank # not always present
9
+
10
+ def initialize(key_values={})
11
+ @identifiers = extract_many_as(key_values, "Identifiers", IActionable::Objects::Identifier)
12
+ @points = extract_many_as(key_values, "Points", IActionable::Objects::ProfilePoints)
13
+ @recent_achievements = extract_many_as(key_values, "RecentAchievements", IActionable::Objects::Achievement)
14
+
15
+ super(key_values)
16
+ end
17
+
18
+ def to_hash
19
+ hash = {
20
+ "DisplayName" => @display_name,
21
+ "Identifiers" => @identifiers.map{|identifier| identifier.to_hash}
22
+ }
23
+ unless @points.nil?
24
+ hash["Points"] = @points.kind_of?(Array) ? @points.map{|point| point.to_hash} : @points
25
+ end
26
+ hash["RecentAchievements"] = @recent_achievements.map{|recent_achievement| recent_achievement.to_hash} unless @recent_achievements.empty?
27
+ hash["Rank"] = @rank unless @rank.nil?
28
+ hash
29
+ end
30
+ end
31
+ end
32
+ end
@@ -0,0 +1,46 @@
1
+ module IActionable
2
+ module Objects
3
+ class Progress < IActionableObject
4
+ attr_accessor :description
5
+ attr_accessor :condition_met_date
6
+ attr_accessor :original_condition_met_date
7
+ attr_accessor :current_value
8
+ attr_accessor :required_value
9
+ attr :complete
10
+
11
+ def initialize(key_values={})
12
+ super(key_values)
13
+ # convert the miliseconds within the date string to seconds (per ruby)
14
+ # "/Date(1275706032317-0600)/" => "1275706032-0600"
15
+ @original_condition_met_date = @condition_met_date
16
+ @condition_met_date = IActionableObject.timestamp_to_seconds(@condition_met_date) unless @condition_met_date.blank?
17
+ end
18
+
19
+ def complete?
20
+ Integer(@current_value) >= Integer(@required_value)
21
+ rescue TypeError => e
22
+ false
23
+ end
24
+
25
+ def percent_complete
26
+ Integer(Float(@current_value) / Integer(@required_value) * 100)
27
+ rescue TypeError => e
28
+ 0
29
+ end
30
+
31
+ def condition_met_date
32
+ # bug in ruby 1.9.2 where Time.strptime does not support seconds-since-epoch format, but Date.strptime does, so we'll use that for now
33
+ Date.strptime(@condition_met_date, "%s%z").to_time unless @condition_met_date.blank?
34
+ end
35
+
36
+ def to_hash
37
+ {
38
+ "Description" => @description,
39
+ "CurrentValue" => @current_value,
40
+ "RequiredValue" => @required_value,
41
+ "ConditionMetDate" => @original_condition_met_date
42
+ }
43
+ end
44
+ end
45
+ end
46
+ end
@@ -0,0 +1,27 @@
1
+ module IActionable
2
+ module Objects
3
+ end
4
+ end
5
+
6
+ require 'iactionable/objects/i_actionable_object.rb'
7
+ require 'iactionable/objects/progress.rb'
8
+ require 'iactionable/objects/awardable.rb'
9
+
10
+ IActionable::Objects::IActionableObject.send(:include, IActionable::Objects::Awardable)
11
+
12
+ require 'iactionable/objects/achievement.rb'
13
+ require 'iactionable/objects/challenge.rb'
14
+ require 'iactionable/objects/goal.rb'
15
+ require 'iactionable/objects/identifier.rb'
16
+ require 'iactionable/objects/leaderboard.rb'
17
+ require 'iactionable/objects/leaderboard_report.rb'
18
+ require 'iactionable/objects/level_type.rb'
19
+ require 'iactionable/objects/level.rb'
20
+ require 'iactionable/objects/point_type.rb'
21
+ require 'iactionable/objects/profile_level.rb'
22
+ require 'iactionable/objects/profile_points.rb'
23
+ require 'iactionable/objects/profile_summary.rb'
24
+ require 'iactionable/objects/profile_achievements.rb'
25
+ require 'iactionable/objects/profile_challenges.rb'
26
+ require 'iactionable/objects/profile_goals.rb'
27
+ require 'iactionable/objects/profile_notifications.rb'
@@ -0,0 +1,30 @@
1
+ module IActionable
2
+ class ConfigError < StandardError
3
+ end
4
+
5
+ class Settings
6
+ attr :settings
7
+
8
+ def initialize(values)
9
+ @settings = {
10
+ :app_key => values.fetch(:app_key),
11
+ :api_key => values.fetch(:api_key),
12
+ :version => values.fetch(:version)
13
+ }
14
+ rescue NoMethodError, KeyError => e
15
+ raise ConfigError.new("IAction::Settings being initialized with invalid arguments")
16
+ end
17
+
18
+ def app_key
19
+ @settings.fetch(:app_key)
20
+ end
21
+
22
+ def api_key
23
+ @settings.fetch(:api_key)
24
+ end
25
+
26
+ def version
27
+ @settings.fetch(:version)
28
+ end
29
+ end
30
+ end
@@ -0,0 +1,3 @@
1
+ module IActionable
2
+ VERSION = "0.0.1"
3
+ end
@@ -0,0 +1,9 @@
1
+ require 'active_support/inflector'
2
+ require 'active_support/core_ext/object/blank'
3
+ require 'active_support/core_ext/date/conversions'
4
+ require 'active_support/core_ext/time/calculations'
5
+ require 'iactionable/version'
6
+ require 'iactionable/api.rb'
7
+
8
+ module IActionable
9
+ end
@@ -0,0 +1,28 @@
1
+ # -*- encoding: utf-8 -*-
2
+ $:.push File.expand_path("../lib", __FILE__)
3
+ require "iactionable/version"
4
+
5
+ Gem::Specification.new do |s|
6
+ s.name = "ruby-iactionable"
7
+ s.version = IActionable::VERSION
8
+ s.authors = ["Chris Eberz"]
9
+ s.email = ["ceberz@elctech.com"]
10
+ s.homepage = ""
11
+ s.summary = %q{Ruby wrapper for IActionable's restful API.}
12
+ s.description = %q{Ruby wrapper for IActionable's restful API.}
13
+
14
+ s.rubyforge_project = "ruby-iactionable"
15
+
16
+ s.files = `git ls-files`.split("\n")
17
+ s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
18
+ s.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
19
+ s.require_paths = ["lib", "spec"]
20
+
21
+
22
+ s.add_development_dependency "rspec", ">= 2.6"
23
+
24
+ s.add_runtime_dependency "rake"
25
+ s.add_runtime_dependency "faraday"
26
+ s.add_runtime_dependency "faraday-stack"
27
+ s.add_runtime_dependency "activesupport", ">= 3.0.0"
28
+ end
@@ -0,0 +1,46 @@
1
+ require 'spec_helper.rb'
2
+
3
+ describe "API response to get_achievements" do
4
+ before do
5
+ @sample_response = [
6
+ {
7
+ "Key" => "opinionated_gold",
8
+ "Description" => "Leave 25 comments.",
9
+ "ImageURL" => "http://iactionable.blob.core.windows.net/achievementimages/33333",
10
+ "Name" => "Opinionated - Gold"
11
+ },
12
+ {
13
+ "Key" => "opinionated_silver",
14
+ "Description" => "Make 10 comments.",
15
+ "ImageURL" => "http://iactionable.blob.core.windows.net/achievementimages/44444",
16
+ "Name" => "Opinionated - Silver"
17
+ }
18
+ ]
19
+ end
20
+
21
+ it "should not raise error on wrapping in an object" do
22
+ lambda { @sample_response.map{|data| IActionable::Objects::Achievement.new(data) } }.should_not raise_error
23
+ end
24
+
25
+ describe "when wrapped in an object" do
26
+ before do
27
+ @wrapped = @sample_response.map{|data| IActionable::Objects::Achievement.new(data) }
28
+ end
29
+
30
+ it "should contain ar array of available achievements" do
31
+ @wrapped.should be_instance_of Array
32
+ @wrapped.first.key.should == @sample_response[0]["Key"]
33
+ @wrapped.first.description.should == @sample_response[0]["Description"]
34
+ @wrapped.first.image_url.should == @sample_response[0]["ImageURL"]
35
+ @wrapped.first.name.should == @sample_response[0]["Name"]
36
+ @wrapped.last.key.should == @sample_response[1]["Key"]
37
+ @wrapped.last.description.should == @sample_response[1]["Description"]
38
+ @wrapped.last.image_url.should == @sample_response[1]["ImageURL"]
39
+ @wrapped.last.name.should == @sample_response[1]["Name"]
40
+ end
41
+
42
+ it "should convert to a hash equal to the original" do
43
+ hash_including(:array => @sample_response).should == {:array => @wrapped.map{|achievement| achievement.to_hash}}
44
+ end
45
+ end
46
+ end
@@ -0,0 +1,42 @@
1
+ require 'spec_helper.rb'
2
+
3
+ describe "API response to get_challenges" do
4
+ before do
5
+ @sample_response = [
6
+ {
7
+ "Key" => "easy_challenge",
8
+ "Description" => "Do something easy 5 times and earn 100 points",
9
+ "Name" => "Easy Challenge"
10
+ },
11
+ {
12
+ "Key" => "hard_challenge",
13
+ "Description" => "Do something hard 10 times and earn 200 points",
14
+ "Name" => "Hard Challenge"
15
+ }
16
+ ]
17
+ end
18
+
19
+ it "should not raise error on wrapping in an object" do
20
+ lambda { @sample_response.map{|data| IActionable::Objects::Challenge.new(data) } }.should_not raise_error
21
+ end
22
+
23
+ describe "when wrapped in an object" do
24
+ before do
25
+ @wrapped = @sample_response.map{|data| IActionable::Objects::Challenge.new(data) }
26
+ end
27
+
28
+ it "should contain ar array of available challenges" do
29
+ @wrapped.should be_instance_of Array
30
+ @wrapped.first.key.should == @sample_response[0]["Key"]
31
+ @wrapped.first.description.should == @sample_response[0]["Description"]
32
+ @wrapped.first.name.should == @sample_response[0]["Name"]
33
+ @wrapped.last.key.should == @sample_response[1]["Key"]
34
+ @wrapped.last.description.should == @sample_response[1]["Description"]
35
+ @wrapped.last.name.should == @sample_response[1]["Name"]
36
+ end
37
+
38
+ it "should convert to a hash equal to the original" do
39
+ hash_including(:array => @sample_response).should == {:array => @wrapped.map{|challenge| challenge.to_hash}}
40
+ end
41
+ end
42
+ end
@@ -0,0 +1,46 @@
1
+ require 'spec_helper.rb'
2
+
3
+ describe "API response to get_goals" do
4
+ before do
5
+ @sample_response = [
6
+ {
7
+ "Key" => "easy_goal",
8
+ "Description" => "Do something easy 5 times today and earn 100 points",
9
+ "Name" => "Easy Goal",
10
+ "Interval" => "Daily"
11
+ },
12
+ {
13
+ "Key" => "hard_goal",
14
+ "Description" => "Do something hard 10 times this week and earn 200 points",
15
+ "Name" => "Hard Goal",
16
+ "Interval" => "Daily"
17
+ }
18
+ ]
19
+ end
20
+
21
+ it "should not raise error on wrapping in an object" do
22
+ lambda { @sample_response.map{|data| IActionable::Objects::Goal.new(data) } }.should_not raise_error
23
+ end
24
+
25
+ describe "when wrapped in an object" do
26
+ before do
27
+ @wrapped = @sample_response.map{|data| IActionable::Objects::Goal.new(data) }
28
+ end
29
+
30
+ it "should contain ar array of available goals" do
31
+ @wrapped.should be_instance_of Array
32
+ @wrapped.first.key.should == @sample_response[0]["Key"]
33
+ @wrapped.first.description.should == @sample_response[0]["Description"]
34
+ @wrapped.first.name.should == @sample_response[0]["Name"]
35
+ @wrapped.first.interval.should == @sample_response[0]["Interval"]
36
+ @wrapped.last.key.should == @sample_response[1]["Key"]
37
+ @wrapped.last.description.should == @sample_response[1]["Description"]
38
+ @wrapped.last.name.should == @sample_response[1]["Name"]
39
+ @wrapped.last.interval.should == @sample_response[1]["Interval"]
40
+ end
41
+
42
+ it "should convert to a hash equal to the original" do
43
+ hash_including(:array => @sample_response).should == {:array => @wrapped.map{|goal| goal.to_hash}}
44
+ end
45
+ end
46
+ end
@@ -0,0 +1,76 @@
1
+ require 'spec_helper.rb'
2
+
3
+ describe "API response to get_leaderboard" do
4
+ before do
5
+ @sample_response = {
6
+ "Leaderboard" => {
7
+ "Key" => "weekly_leaderboard",
8
+ "Name" => "Weekly Experience Points Leaderboard"
9
+ },
10
+ "PageCount" => 10,
11
+ "PageNumber" => 1,
12
+ "PointType" => {
13
+ "Key" => "experience_points",
14
+ "Name" => "Experience Points"
15
+ },
16
+ "Profiles" => [
17
+ {
18
+ "DisplayName" => "Jimmy Dean",
19
+ "Identifiers" => [
20
+ {
21
+ "ID" => "100005",
22
+ "IDHash" => "d63c48a193f960380f0ac353eddc25d4",
23
+ "IDType" => "Facebook"
24
+ }
25
+ ],
26
+ "Rank" => 1,
27
+ "Points" => 246
28
+ },
29
+ {
30
+ "DisplayName" => "Jason Barnes",
31
+ "Identifiers" => [
32
+ {
33
+ "ID" => "100010",
34
+ "IDHash" => "d3d33fb3e33963b58f681ed2e98d835c",
35
+ "IDType" => "Facebook"
36
+ },
37
+ {
38
+ "ID" => "email@dot.com",
39
+ "IDHash" => "66a1bd06edcc1a2d208953d441e1374e",
40
+ "IDType" => "Email"
41
+ }
42
+ ],
43
+ "Rank" => 2,
44
+ "Points" => 216
45
+ },
46
+ {
47
+ "DisplayName" => "Ben Burt",
48
+ "Identifiers" => [
49
+ {
50
+ "ID" => "600004",
51
+ "IDHash" => "e567689d28abc93867955ff85324bd08",
52
+ "IDType" => "Facebook"
53
+ }
54
+ ],
55
+ "Rank" => 3,
56
+ "Points" => 50
57
+ }
58
+ ],
59
+ "TotalCount" => 50
60
+ }
61
+ end
62
+
63
+ it "should not raise error on wrapping in an object" do
64
+ lambda { IActionable::Objects::LeaderboardReport.new(@sample_response) }.should_not raise_error
65
+ end
66
+
67
+ describe "when wrapped in an object" do
68
+ before do
69
+ @wrapped = IActionable::Objects::LeaderboardReport.new(Marshal.load(Marshal.dump(@sample_response)))
70
+ end
71
+
72
+ it "should convert to a hash equal to the original" do
73
+ hash_including(@sample_response).should == @wrapped.to_hash
74
+ end
75
+ end
76
+ end