gamifier 1.0.8 → 1.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
data/.rspec ADDED
@@ -0,0 +1 @@
1
+ --color
data/README.md CHANGED
@@ -22,6 +22,12 @@ Or install it yourself as:
22
22
  Configure Gamifier with the right parameter for the API you're using:
23
23
 
24
24
  Gamifier.set :key => "1234", :uri => "http://sandbox.v2.badgeville.com/api/berlin/"
25
+
26
+ Gamifier support the last version of Badgeville API using *enterprise api key*:
27
+
28
+ Gamifier.set :key => '1234', :uri => "http://sandbox.v2.badgeville.com/api/berlin/", :enterprise_key => '5678'
29
+
30
+ *Note that you have to specify either a private API key or an enterprise API key.*
25
31
 
26
32
  Then here is an example usage to credit an existing player:
27
33
 
@@ -35,16 +41,58 @@ declare activities, rewards and missions, and you can execute a DSL as
35
41
  follows:
36
42
 
37
43
  BADGEVILLE_KEY=xzy bundle exec ruby -I lib examples/dev.rb
44
+
45
+ ## Create Network using the DSL
46
+
47
+ Since the new Badgeville API, you can create new Network and API Keys using the Badgeville API. We updated the DSL for you:
48
+
49
+ network = Gamifier.dsl do
50
+ set :label, 'MyNetwork'
51
+ set :email, 'dev@mynetwork.com'
52
+
53
+ api_key do
54
+ set :access, 'public'
55
+ end
56
+
57
+ api_key do
58
+ set :access, 'private'
59
+ end
60
+
61
+ site 'foo' do
62
+ # as usual here
63
+ end
64
+ end
65
+
66
+ To only save the network on Badgeville do:
67
+
68
+ network.save_network!
69
+
70
+ To only save the sites, behaviors, rewards, etc do:
71
+
72
+ network.save!
73
+
74
+ If you want to create a new Network and create Sites, Behaviors, Rewards, etc on that new Network, you'll need the network's private API key.
75
+
76
+ api_key do
77
+ set :access, 'private'
78
+ end
79
+
80
+ These lines will create a new Private API key on current network. You'll need to:
81
+
82
+ 1. Create and Save the network: `network.save_network!`
83
+ 2. Create and Save the sites, behaviors and so on: `network.save!`
84
+
85
+ `network.save!` will use by default the new private API key if any, otherwise it will fallback to Gamifier's config.
38
86
 
39
87
  ## Tests
40
88
 
41
89
  Run the unit tests with:
42
90
 
43
- bundle exec spec spec/unit
91
+ bundle exec rspec spec/unit
44
92
 
45
93
  Run the integration tests as follows:
46
94
 
47
- BADGEVILLE_KEY=1234 bundle exec spec spec/integration
95
+ BADGEVILLE_KEY=1234 bundle exec rspec spec/integration
48
96
 
49
97
  ## Contributing
50
98
 
@@ -52,9 +100,13 @@ Run the integration tests as follows:
52
100
  2. Create your feature branch (`git checkout -b my-new-feature`)
53
101
  3. Commit your changes (`git commit -am 'Added some feature'`)
54
102
  4. Push to the branch (`git push origin my-new-feature`)
55
- 5. Create new Pull Request
103
+ 5. Create new Pull Request on Github
56
104
 
57
105
 
58
106
  ## Authors
59
107
 
60
108
  * Cyril Rohr <cyril.rohr@gmail.com>
109
+
110
+ ## Contributors
111
+
112
+ * [Pierre-Louis Gottfrois](https://github.com/gottfrois)
data/examples/dev.rb CHANGED
@@ -1,10 +1,21 @@
1
1
  require 'gamifier'
2
2
  require 'json'
3
3
 
4
- Gamifier.set :uri => "http://sandbox.v2.badgeville.com/api/berlin/", :key => ENV.fetch('BADGEVILLE_KEY')
4
+ Gamifier.set :uri => "http://sandbox.v2.badgeville.com/api/berlin/", :key => ENV.fetch('BADGEVILLE_KEY'), :enterprise_key => ENV.fetch('BADGEVILLE_ENTERPRISE_KEY')
5
5
  Gamifier.logger.level = Logger::DEBUG
6
6
 
7
7
  network = Gamifier.dsl do
8
+ set :label, 'MyNetwork'
9
+ set :email, 'dev@mynetwork.com'
10
+
11
+ api_key do
12
+ set :access, 'public'
13
+ end
14
+
15
+ api_key do
16
+ set :access, 'private'
17
+ end
18
+
8
19
  site 'dev.domain-test.crohr.me' do |site|
9
20
  set :url, 'dev.domain-test.crohr.me'
10
21
 
@@ -69,15 +80,15 @@ network = Gamifier.dsl do
69
80
  # set :adjustment, {
70
81
  # :points => 1, :karma => 1
71
82
  # }
72
- #
83
+ #
73
84
  # set :enable_count_limiting, true
74
85
  # set :limit_per_player, 10
75
86
  # set :limit_field_scope, 'category_id'
76
- #
87
+ #
77
88
  # set :enable_rate_limiting, true
78
89
  # set :bucket_max_capacity, 2
79
90
  # set :bucket_drain_rate, bucket_max_capacity/1.5
80
- #
91
+ #
81
92
  # set :hide_in_widgets, false
82
93
  # set :icon, "http://s3.amazonaws.com/icons/icon1.png"
83
94
  # end
@@ -95,7 +106,7 @@ network = Gamifier.dsl do
95
106
  set :active, true
96
107
  set :allow_duplicates, false
97
108
  end
98
-
109
+
99
110
  r_active_member = reward 'active member' do
100
111
  set :reward_template, {
101
112
  :message => "Looks like you like the site, thank you and keep up on being active on the site!"
@@ -123,7 +134,7 @@ network = Gamifier.dsl do
123
134
  set :active, true
124
135
  set :allow_duplicates, false
125
136
  end
126
-
137
+
127
138
  r_active_commenter = reward 'active commenter' do
128
139
  set :reward_template, {
129
140
  :message => "You have commented more than 3 times in any category!"
@@ -183,4 +194,4 @@ network = Gamifier.dsl do
183
194
  end
184
195
  end
185
196
 
186
- network.save!
197
+ network.save!
@@ -0,0 +1,19 @@
1
+ module Gamifier
2
+ module DSL
3
+ class ApiKey
4
+ attr_reader :source
5
+
6
+ def initialize(*args)
7
+ @source = ::Gamifier::ApiKey.new(*args)
8
+ end
9
+
10
+ def engine
11
+ source.engine
12
+ end
13
+
14
+ def method_missing(*args, &block)
15
+ source.send(*args, &block)
16
+ end
17
+ end
18
+ end
19
+ end
@@ -6,28 +6,82 @@ module Gamifier
6
6
  extend Forwardable
7
7
  def_delegator :Gamifier, :engine, :engine
8
8
 
9
+ attr_reader :source
9
10
  attr_reader :sites
11
+ attr_reader :api_keys
10
12
 
11
- def initialize
12
- @sites = []
13
+ def initialize(*args)
14
+ @source = ::Gamifier::Network.new(*args)
15
+ @sites = []
16
+ @api_keys = []
17
+ end
18
+
19
+ def engine
20
+ @engine ||= Gamifier::Engine.new(:key => get_key('private') || Gamifier.config[:key])
21
+ end
22
+
23
+ def enterprise_engine
24
+ raise ArgumentError, "You must specify an enterprise key" unless Gamifier.config[:enterprise_key]
25
+ @enterprise_engine ||= Gamifier::Engine.new(:key => Gamifier.config[:enterprise_key])
13
26
  end
14
27
 
15
28
  def site(name, &block)
16
29
  new_site = DSL::Site.new(:name => name)
17
- new_site.source.engine = engine
18
30
  @sites.push(new_site)
19
31
 
20
32
  DSL.eval_with_context(new_site, &block)
21
33
  end
22
-
23
- def save!
34
+
35
+ def api_key(&block)
36
+ new_key = DSL::ApiKey.new
37
+ new_key.source.engine = enterprise_engine
38
+ @api_keys.push(new_key)
39
+
40
+ DSL.eval_with_context(new_key, &block)
41
+ end
42
+
43
+ def save_network!
44
+ begin
45
+ if self.save
46
+ save_api_keys!
47
+ end
48
+ rescue
49
+ Gamifier.logger.debug "Can't save #{self}"
50
+ end
51
+ end
52
+
53
+ def save_api_keys!
54
+ api_keys.each do |key|
55
+ key.engine = enterprise_engine
56
+ key.network_id = self.id
57
+ key.save
58
+ end
59
+ end
60
+
61
+ def save_sites!
24
62
  sites.each do |site|
25
63
  if gsite = engine.sites.find(site.url)
26
64
  site._id = gsite._id
27
65
  end
66
+ site.engine = engine
28
67
  site.save
29
68
  end
30
69
  end
70
+
71
+ def get_key(access = 'private')
72
+ key = self.api_keys.select {|k| k.access == access}.first
73
+ return key.key if key
74
+ nil
75
+ end
76
+
77
+ def save!
78
+ save_sites!
79
+ end
80
+
81
+ def method_missing(*args, &block)
82
+ source.send(*args, &block)
83
+ end
84
+
31
85
  end
32
86
  end
33
- end
87
+ end
@@ -78,6 +78,7 @@ module Gamifier
78
78
  # response, remove the next line:
79
79
  next
80
80
  end
81
+ unit.engine = engine
81
82
  unit.save || raise(Error, "Can't save #{unit}")
82
83
  end
83
84
  end
@@ -89,6 +90,7 @@ module Gamifier
89
90
  if gbehavior = engine.send(behavior.class.path).find_by_name(behavior.name, :site => self.url)
90
91
  behavior._id = gbehavior._id
91
92
  end
93
+ behavior.engine = engine
92
94
  behavior.save || raise(Error, "Can't save #{behavior}")
93
95
  end
94
96
  end
@@ -100,6 +102,7 @@ module Gamifier
100
102
  if greward = engine.send(reward.class.path).find_by_name(reward.name, :site => self.url)
101
103
  reward._id = greward._id
102
104
  end
105
+ reward.engine = engine
103
106
  reward.save || raise(Error, "Can't save #{reward}")
104
107
  end
105
108
  end
@@ -111,6 +114,7 @@ module Gamifier
111
114
  if gmission = engine.send(mission.class.path).find_by_name(mission.name, :site => self.url)
112
115
  mission._id = gmission._id
113
116
  end
117
+ mission.engine = engine
114
118
  mission.save || raise(Error, "Can't save #{mission}")
115
119
  end
116
120
  end
@@ -122,6 +126,7 @@ module Gamifier
122
126
  if gtrack = engine.send(track.class.path).find_by_label(track.label, :site => self.url)
123
127
  track._id = gtrack._id
124
128
  end
129
+ track.engine = engine
125
130
  track.save || raise(Error, "Can't save #{track}")
126
131
  end
127
132
  end
data/lib/gamifier/dsl.rb CHANGED
@@ -1,4 +1,5 @@
1
1
  require 'gamifier/dsl/network'
2
+ require 'gamifier/dsl/api_key'
2
3
  require 'gamifier/dsl/site'
3
4
 
4
5
  module Gamifier
@@ -12,7 +13,7 @@ module Gamifier
12
13
  new_context
13
14
  end
14
15
  end
15
-
16
+
16
17
  def set(key, *args, &block)
17
18
  if block
18
19
  self.send("#{key}=".to_sym, block)
@@ -21,4 +22,4 @@ module Gamifier
21
22
  end
22
23
  end
23
24
  end
24
- end
25
+ end
@@ -4,7 +4,7 @@ require 'gamifier/collection'
4
4
 
5
5
  module Gamifier
6
6
  class Engine
7
- MODELS = %w{Activity ActivityDefinition Group Player Reward RewardDefinition Site Track Unit User}
7
+ MODELS = %w{ApiKey Network Activity ActivityDefinition Group Player Reward RewardDefinition Site Track Unit User}
8
8
 
9
9
  attr_accessor :connection
10
10
  attr_writer :config
@@ -26,7 +26,11 @@ module Gamifier
26
26
  end
27
27
 
28
28
  def ok?
29
- !config.values_at(:key, :uri).any?{|k| k.nil? || k.empty?}
29
+ if config[:enterprise_key].nil? || config[:enterprise_key].empty?
30
+ !config.values_at(:key, :uri).any?{|k| k.nil? || k.empty?}
31
+ else
32
+ !(config[:uri].nil? || config[:uri].empty?)
33
+ end
30
34
  end
31
35
 
32
36
  # Sends an HTTP request corresponding to +method+, on +path+, with
@@ -65,8 +69,8 @@ module Gamifier
65
69
  end
66
70
  end
67
71
 
68
- def uri_to(path = "")
69
- URI.join(File.join(::Gamifier.config[:uri], ::Gamifier.config[:key], ""), path)
72
+ def uri_to(path = '')
73
+ URI.join(File.join(self.config[:uri], self.config[:key] || '', ''), path)
70
74
  end
71
75
 
72
76
  MODELS.each do |model|
@@ -0,0 +1,10 @@
1
+ require 'gamifier/model'
2
+
3
+ module Gamifier
4
+ class ApiKey < Model
5
+ def engine
6
+ raise ArgumentError, "You must specify an enterprise key" unless Gamifier.config[:enterprise_key]
7
+ @engine ||= Gamifier::Engine.new(:key => Gamifier.config[:enterprise_key])
8
+ end
9
+ end
10
+ end
@@ -0,0 +1,10 @@
1
+ require 'gamifier/model'
2
+
3
+ module Gamifier
4
+ class Network < Model
5
+ def engine
6
+ raise ArgumentError, "You must specify an enterprise key" unless Gamifier.config[:enterprise_key]
7
+ @engine ||= Gamifier::Engine.new(:key => Gamifier.config[:enterprise_key])
8
+ end
9
+ end
10
+ end
@@ -1,3 +1,3 @@
1
1
  module Gamifier
2
- VERSION = "1.0.8" unless defined?(Gamifier::VERSION)
2
+ VERSION = "1.1.0" unless defined?(Gamifier::VERSION)
3
3
  end
data/lib/gamifier.rb CHANGED
@@ -33,9 +33,9 @@ module Gamifier
33
33
 
34
34
  # Creates and returns a new DSL::Network object. The given block
35
35
  # will be evaluated in the context of the network object.
36
- #
36
+ #
37
37
  # Usage:
38
- #
38
+ #
39
39
  # network = Gamifier.dsl do
40
40
  # site 'my-site' do
41
41
  # set :url, 'my-site.com'
@@ -44,8 +44,7 @@ module Gamifier
44
44
  # end
45
45
  def dsl(&block)
46
46
  network = DSL::Network.new
47
- network.instance_eval(&block)
48
- network
47
+ DSL.eval_with_context(network, &block)
49
48
  end
50
49
 
51
50
  def logger
@@ -2,19 +2,19 @@ require 'spec_integration_helper'
2
2
 
3
3
  describe "managing collections" do
4
4
  before :all do
5
- @site = ENGINE.sites.find("ibadgedyou.dev")
5
+ @site = Gamifier.engine.sites.find("ibadgedyou.dev")
6
6
  @site.should_not be_nil
7
- ENGINE.activity_definitions.reset!(:site => "ibadgedyou.dev")
7
+ Gamifier.engine.activity_definitions.reset!(:site => "ibadgedyou.dev")
8
8
  end
9
9
 
10
10
  it "should list all players" do
11
11
  3.times do |i|
12
- behavior = ENGINE.activity_definitions.build({:selector => {:verb => "visit#{i}"}, :name => "visit#{i}", :site_id => @site._id}).save
12
+ behavior = Gamifier.engine.activity_definitions.build({:selector => {:verb => "visit#{i}"}, :name => "visit#{i}", :site_id => @site._id}).save
13
13
  behavior.should_not be_nil
14
14
  end
15
- ENGINE.activity_definitions.all(:site => "ibadgedyou.dev").length.should == 3
16
- ENGINE.activity_definitions.reset!(:site => "ibadgedyou.dev")
17
- ENGINE.activity_definitions.all(:site => "ibadgedyou.dev").length.should == 0
15
+ Gamifier.engine.activity_definitions.all(:site => "ibadgedyou.dev").length.should eq 3
16
+ Gamifier.engine.activity_definitions.reset!(:site => "ibadgedyou.dev")
17
+ Gamifier.engine.activity_definitions.all(:site => "ibadgedyou.dev").length.should eq 0
18
18
  end
19
19
 
20
20
  end
@@ -1,76 +1,72 @@
1
- require 'spec_integration_helper'
1
+ require 'spec_helper'
2
2
 
3
3
  describe "DSL" do
4
- before do
5
- @network = Gamifier.dsl do
6
- site 'mydomain' do
7
- set :url, 'mydomain.com'
4
+
5
+ let(:url) { 'http://foo.com' }
6
+ let(:key) { '1234' }
7
+ let(:enterprise_key) { '5678' }
8
+ let(:network) {
9
+ Gamifier.dsl do
10
+ set :label, 'foo'
11
+ set :email, 'foo@bar.com'
12
+
13
+ api_key do
14
+ set :access, 'private'
15
+ end
16
+
17
+ site 'foo' do
18
+ set :url, 'bar.com'
8
19
 
9
20
  unit :karma do
10
- set :label, 'Karma'
21
+ set :label, 'karma'
11
22
  set :abbreviation, 'kar'
12
23
  end
24
+ end
13
25
 
14
- behavior 'new comment' do
15
- set :description, "new comment behaviour"
16
- set :selector, {
17
- :verb => 'new_comment',
18
- :category_id => 'hello'
19
- }
20
- set :adjustment, {
21
- :points => 15, :karma => 10
22
- }
23
-
24
- set :enable_count_limiting, true
25
- set :limit_per_player, 10
26
- set :limit_field_scope, 'category_id'
27
-
28
- set :enable_rate_limiting, true
29
- set :bucket_max_capacity, 2
30
- set :bucket_drain_rate, bucket_max_capacity/1.5
31
-
32
- set :hide_in_widgets, false
33
- set :icon, "http://crohr.me/images/cyrilrohr.jpg"
34
- end
26
+ end
27
+ }
35
28
 
29
+ let(:network_response) { '{"id":"5112257849f8387b000e85f6","label":"foo","email":"foo@bar.com","api_explorer_post":null,"permissions":{"api_explorer_posting":true,"social_mechanics":true,"read_only_widgets":true,"show_community_link":true},"attempts":20,"timeout":180,"whitelist_filter":null,"require_strong_passwords":false,"password_reset_in_days":60,"force_password_resets":false,"deny_previous_passwords":false,"enable_ip_whitelist":false}' }
30
+ let(:site_response) { '{"name":"foo","created_at":"2013-02-06T01:44:22-08:00","url":"bar.com","id":"511225f6297c011c62106fb7","_id":"511225f6297c011c62106fb7","network_id":"4fac5d4f3dc6483a0100000b","timed_reset":false,"reset_interval":null,"reset_month":null,"reset_date":null,"reset_day":null,"reset_hour":null,"interval_start":null,"interval_end":null}' }
31
+ let(:unit_response) { '{"id":"511226da297c011c4b11543e","name":"karma","label":"karma","normalized_name":"unit_karma","type":"point","abbreviation":"kar","display_priority":0}' }
36
32
 
37
- r1 = reward 'top commenter' do
38
- set :reward_template, {
39
- :message => "Congrats!"
40
- }
41
- set :components, [
42
- {:command => "count", :comparator => 1, :where => {:verb => 'new_comment', :player_id => "%player_id"}},
43
- # the first player who performs at least twice the 'new_question' behaviour
44
- {:command => "count", :comparator => {"$gt" => 2}, :where => {:verb => 'new_question', :site_id => "%site_id"}}
45
- ]
46
- set :adjustment, {
47
- :points => 5
48
- }
49
- set :active, true
50
- set :allow_duplicates, false
51
- end
52
-
53
- m1 = mission 'community member' do
54
- # allow a player to complete this mission more than once?
55
- set :repeatable, false
56
- set :active, true
57
- # give points and reward upon completing mission? (This is required for track progression)
58
- set :enable_rewards, true
59
- # points and secondary units to award when completing a mission
60
- set :adjustment, {
61
- :points => 10
62
- }
63
- set :reward_definition_ids do [r1._id] end
64
- end
65
-
66
- track 'commenting' do
67
- set :group_definition_ids do [m1._id] end
68
- end
69
- end
33
+ before do
34
+ stub_request(:get, "#{url}/#{key}/sites/bar.com.json").to_return(:status => 404, :body => '')
35
+ stub_request(:post, "#{url}/#{key}/sites.json").to_return(:status => 200, :body => site_response)
36
+ stub_request(:get, "#{url}/#{key}/units.json?page=1&per_page=50&site=bar.com").to_return(:status => 404, :body => '')
37
+ stub_request(:post, "#{url}/#{key}/units.json").to_return(:status => 200, :body => unit_response)
38
+ Gamifier.set :uri => url, :key => key, :enterprise_key => enterprise_key
39
+ end
40
+
41
+ context "when network already exists" do
42
+
43
+ let(:network_error_response) { '{"name":["is already taken"],"label":["is already taken"]}' }
44
+
45
+ before do
46
+ stub_request(:post, "#{url}/#{enterprise_key}/networks.json").to_return(:status => 422, :body => network_error_response)
47
+ end
48
+
49
+ it { expect { network.save_network! }.to_not raise_error }
50
+
51
+ end
52
+
53
+ context "when network does not exists" do
54
+
55
+ let(:api_key_response) { '{"id":"51122b073dc6480b760f66ce","network_id":"5112257849f8387b000e85f6","key":"5c3782a61ff639c92c30ea73d294e25e","access":"private","enable_whitelist":false,"ip_addresses":null}' }
56
+
57
+ before do
58
+ stub_request(:post, "#{url}/#{enterprise_key}/networks.json").to_return(:status => 200, :body => network_response)
59
+ stub_request(:post, "#{url}/#{enterprise_key}/api_keys.json").to_return(:status => 200, :body => api_key_response)
70
60
  end
61
+
62
+ it { expect { network.save_network! }.to_not raise_error }
63
+
71
64
  end
65
+
66
+ it { expect{ network.save! }.to_not raise_error }
67
+
72
68
  it "should work twice" do
73
- expect{ @network.save! }.to_not raise_error
74
- expect{ @network.save! }.to_not raise_error
69
+ expect{ network.save! }.to_not raise_error
70
+ expect{ network.save! }.to_not raise_error
75
71
  end
76
- end
72
+ end
@@ -1,23 +1,25 @@
1
1
  require 'spec_integration_helper'
2
2
 
3
3
  describe "managing players" do
4
- before :all do
4
+
5
+ before do
5
6
  destroy_test_player!
6
7
  end
7
8
 
8
9
  it "should list all players" do
9
- players = ENGINE.players.all
10
+ players = Gamifier.engine.players.all
10
11
  players.all?{|p| p.kind_of?(Gamifier::Player)}.should be_true
11
12
  end
12
13
 
13
14
  it "should create a new player" do
14
15
  find_or_create_test_user
15
- player = ENGINE.players.build(player_attributes)
16
+ player = Gamifier.engine.players.build(player_attributes)
16
17
  player.save
17
- ENGINE.players.find(player._id).should_not be_nil
18
+ Gamifier.engine.players.find(player._id).should_not be_nil
18
19
  end
19
20
 
20
21
  describe "with an existing player" do
22
+
21
23
  before do
22
24
  @player = find_or_create_test_player
23
25
  end
@@ -34,8 +36,9 @@ describe "managing players" do
34
36
  url = "http://s3.amazonaws.com/crohr.dimelo/identity_avatars/2ffbf54be4af49e7/avatar_normal.png?f59510d"
35
37
  @player.picture_url = url
36
38
  @player.save.should be_true
37
- ENGINE.players.find(@player._id).picture_url.should == url
39
+ Gamifier.engine.players.find(@player._id).picture_url.should == url
38
40
  end
41
+
39
42
  end
40
43
 
41
44
  end
@@ -2,18 +2,27 @@ require 'spec_integration_helper'
2
2
 
3
3
  describe "managing users" do
4
4
 
5
- before :all do
6
- user = ENGINE.users.find(user_attributes[:email])
7
- if user
8
- puts "Found user #{user}. Deleting..."
9
- user.destroy.should be_true
10
- end
5
+ let(:url) { 'http://foo.com' }
6
+ let(:key) { '1234' }
7
+
8
+ before do
9
+ Gamifier.set :uri => url, :key => key
11
10
  end
12
11
 
13
- it "should create a new user" do
14
- user = ENGINE.users.build(user_attributes)
15
- user.should be_new
16
- user.save.should be_true
17
- user.should_not be_new
12
+ context "when user does not exists" do
13
+
14
+ let(:user) { Gamifier.engine.users.build(user_attributes) }
15
+ let(:users_response) { '"name": "Foo Bar","created_at": "2013-02-12T06:13:50-08:00","email": "user@foo.com","_id": "511a4e1e297c0148ed00238c","id": "511a4e1e297c0148ed00238c"' }
16
+
17
+ before do
18
+ stub_request(:post, "#{url}/#{key}/users.json").to_return(:status => 200, :body => users_response)
19
+ end
20
+
21
+ subject { user }
22
+
23
+ it { should be_new }
24
+ it { subject.save.should be_true }
25
+
18
26
  end
19
- end
27
+
28
+ end