todaysplan 0.1.0 → 0.2.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 0f11f6637035fa0e823a298286a69726d6906256
4
- data.tar.gz: a7fccf886bd13b23f2194b558cf7172e259a82fe
3
+ metadata.gz: 0f15a61fe0e7c44b9184e3eec252f2527f7f270d
4
+ data.tar.gz: 702570cbc3b9e829c37a90d9cdc3e3e5f95ab5a1
5
5
  SHA512:
6
- metadata.gz: 35d5eb9895c1c0b3a52bace60d768a6369e00eab837417887dc54f0c858b07eed7a54bf8d887e26b525c7a3ad5c12df902593e286702a97f70034563b4b3cb2a
7
- data.tar.gz: d4ee841df274b6db233af9cef40b40c8d15ed388d9ba7ec816b7032c87648a2ca322e5cbfde7ea7cfd8d67e8223d70eee0ce4542761d8a9b6162f37ef51a324e
6
+ metadata.gz: 21b04b33a7f90c9b8a556f14494f12ff2ea0b51d93e58b061042aede1982fa8bea40d96788ade9f80c270f1f72ffeeaae299f598f48b1cf8c70a7f0ccf93e509
7
+ data.tar.gz: bf26d14ee97f05b2991941b5fca413c12ea878b200bdf164a199eb9bb6add6bbab4cc9ee0278ffa60848d4d114429ea89f68a9c110de4b00485b52ca9f9c3ac4
data/README.md CHANGED
@@ -10,7 +10,7 @@ Pull Request to include additional calls.
10
10
  Add the gem to your app
11
11
 
12
12
  ```ruby
13
- gem 'todaysplan-ruby'
13
+ gem 'todaysplan-ruby', require: 'todays_plan
14
14
  ```
15
15
 
16
16
  ### Usage
@@ -40,4 +40,3 @@ timeout: 120
40
40
  logger: 'stdout'
41
41
  debug: true
42
42
  ```
43
-
@@ -11,6 +11,7 @@ module TodaysPlan
11
11
  attr_reader :coach
12
12
  attr_reader :email
13
13
  attr_reader :dob
14
+ attr_reader :country
14
15
 
15
16
 
16
17
  def initialize(fields)
@@ -18,16 +19,15 @@ module TodaysPlan
18
19
  @name = fields['_name']
19
20
  @first_name = fields['firstname']
20
21
  @last_name = fields['lastname']
21
- @timezone = fields['timezone']
22
+ @timezone =fields['timezone']
22
23
  @coach = fields['coach']["id"].to_i if fields.has_key?("coach")
23
24
  @email = fields['email']
24
25
  @dob = Time.at(fields['dob'].to_i/1000)
26
+ @country = fields['country']
25
27
  end
26
28
 
27
29
  # Find a single athlete
28
- # +client+:: the authenticated client
29
30
  # +id+:: the athlete id
30
- # +options+:: has of options
31
31
  def self.find(id)
32
32
  all().find{|a| a.id==id}
33
33
  end
@@ -39,5 +39,40 @@ module TodaysPlan
39
39
  new(data)
40
40
  end
41
41
  end
42
+
43
+ # Create new Athlete\
44
+ # options
45
+ # user_email - email address of new user
46
+ # firstname - first name of new user
47
+ # lastname - last name of new user
48
+ # password - password of new user
49
+ # coach_email - coach email in todaysplan
50
+ def self.create(options, client = nil)
51
+
52
+ #preregister
53
+ response = RestClient.get("#{TodaysPlan.endpoint}/auth/preregister")
54
+
55
+ # register the user
56
+ payload = {email: options[:user_email], firstname: options[:firstname],
57
+ lastname: options[:lastname], password: options[:password]}
58
+ response = RestClient.post("#{TodaysPlan.endpoint}/auth/register",payload.to_json,
59
+ { content_type: :json})
60
+ response.body
61
+ athlete = new(JSON.parse(response.body))
62
+ # user invites coach
63
+ user_client = TodaysPlan::Client.new(options[:user_email], options[:password])
64
+ invite={"email"=>options[:coach_email],"state"=> "pending_coach",
65
+ "relationship"=> "coach"}.to_json
66
+ response = Connector.new('/users/delegates/invite', user_client).post(invite)
67
+
68
+ # find invitation and accept
69
+ Connector.new('/users/delegates/search/0/100', client).
70
+ post({ "state"=> "pending_coach"}.to_json)["results"].each do |result|
71
+ id = result["id"]
72
+ Connector.new("/users/delegates/invite/accept/#{id}", client).get()
73
+
74
+ end
75
+ athlete
76
+ end
42
77
  end
43
78
  end
@@ -12,28 +12,60 @@ module TodaysPlan
12
12
  #
13
13
  # Returns the parsed JSON response body.
14
14
  def get()
15
- @response = RestClient::Request.execute(method: :get, url: @uri,
16
- timeout: @timeout,
17
- headers: {:Authorization => "Bearer #{@client.token}",accept: :json} )
18
- puts "#{@response.body}" if TodaysPlan.debug
19
- @body = JSON.parse(@response.body)
15
+ options={
16
+ method: :get,
17
+ headers:{ accept: :json}
18
+ }
19
+ run(options)
20
20
  end
21
21
 
22
22
  # Internal: Run GET request.
23
23
  #
24
24
  # Returns the parsed JSON response body.
25
25
  def post(payload = {})
26
- @response = RestClient::Request.execute(method: :post,
27
- payload: payload, url: @uri,
26
+ options={method: :post,
27
+ payload: payload,
28
+ headers:{content_type: :json, accept: :json}
29
+ }
30
+ run(options)
31
+ end
32
+
33
+ private
34
+
35
+ def run(options)
36
+ @response = RestClient::Request.execute(
37
+ method: options[:method],
38
+ payload: options[:payload], url: @uri,
28
39
  timeout: @timeout,
29
- headers:{:Authorization => "Bearer #{@client.token}",
30
- content_type: :json,
31
- accept: :json})
32
- puts "#{@response.body}" if TodaysPlan.debug
40
+ headers: options[:headers].merge({:Authorization => "Bearer #{@client.token}"})
41
+ )
42
+ if @response.body.nil? || @response.body.empty?
43
+ raise TodaysPlan::ServerError.new(0, 'Server error', 'Try to connect later')
44
+ end
45
+
46
+ puts "#{@response.inspect}" if TodaysPlan.debug
47
+
33
48
  @body = JSON.parse(@response.body)
34
- @body
49
+ case @response.code
50
+ when 200..207
51
+ @body
52
+ else
53
+ raise_error
54
+ end
35
55
  end
36
56
 
37
-
57
+ # Internal: Raise an error with the class depending on @response.
58
+ #
59
+ # Returns an Array with arguments.
60
+ def raise_error
61
+ klass = case @response.to_s
62
+ when "RestClient::BadRequest" then TodaysPlan::BadRequestError
63
+ when "RestClient::Unauthorized" then TodaysPlan::UnauthorizedError
64
+ when "RestClient::NotFound" then TodaysPlan::NotFoundError
65
+ else
66
+ TodaysPlan::ServerError
67
+ end
68
+ raise klass.new(body['code'], body['message'], body['resolve'])
69
+ end
38
70
  end
39
71
  end
@@ -0,0 +1,37 @@
1
+ module TodaysPlan
2
+ # Public: Exception to throw when there are configuration problems
3
+ class NotConfiguredError < StandardError; end
4
+
5
+ # Internal: Base class for TodaysPlan errors
6
+ class TodaysPlanError < StandardError
7
+ attr_reader :code, :resolve
8
+
9
+ # Internal: Initialize a error with proper attributes.
10
+ #
11
+ # code - The Integer code (e.g. 1501).
12
+ # message - The String message, describing the error.
13
+ # resolve - The String description how to fix the error.
14
+ def initialize(code, message, resolve)
15
+ @code = code
16
+ @resolve = resolve
17
+
18
+ super "Code #{@code}: #{message}. #{resolve}"
19
+ end
20
+ end
21
+
22
+ # Public: Exception which is thrown when TodaysPlan API returns a 400 response.
23
+ class BadRequestError < TodaysPlanError; end
24
+
25
+ # Public: Exception which is thrown when TodaysPlan API returns a 401 response.
26
+ class UnauthorizedError < TodaysPlanError; end
27
+
28
+ # Public: Exception which is thrown when TodaysPlan API returns a 402 response.
29
+ class RequestFailedError < TodaysPlanError; end
30
+
31
+ # Public: Exception which is thrown when TodaysPlan API returns a 404 response.
32
+ class NotFoundError < TodaysPlanError; end
33
+
34
+ # Public: Exception which is thrown when TodaysPlan API returns a response which
35
+ # is neither 2xx, nor 4xx. Presumably 5xx.
36
+ class ServerError < TodaysPlanError; end
37
+ end
@@ -1,3 +1,3 @@
1
1
  module TodaysPlan
2
- VERSION = '0.1.0'
2
+ VERSION = '0.2.0'
3
3
  end
data/lib/todays_plan.rb CHANGED
@@ -3,6 +3,7 @@ require 'todays_plan/client'
3
3
  require 'todays_plan/connector'
4
4
  require 'todays_plan/athlete'
5
5
  require 'todays_plan/activity'
6
+ require 'todays_plan/errors'
6
7
  require 'rest_client'
7
8
 
8
9
  module TodaysPlan
@@ -0,0 +1,27 @@
1
+ {
2
+ "id": 7171264,
3
+ "coach": {
4
+ "_name": "Coach Joh",
5
+ "id": 7186982,
6
+ "email": "curt@mtbcoach.com",
7
+ "firstname": "Curt",
8
+ "lastname": "Wilhelm",
9
+ "isPremium": true
10
+ },
11
+ "client": {
12
+ "_name": "curt wilhelm",
13
+ "id": 7189071,
14
+ "email": "curt+1@mtbcoach.com",
15
+ "dob": 315532800000,
16
+ "_dob-display": "1/1/80",
17
+ "firstname": "curt",
18
+ "lastname": "wilhelm",
19
+ "relationship": "coach",
20
+ "_relationship-display": "Coach",
21
+ "isPremium": true
22
+ },
23
+ "state": "active",
24
+ "_state-display": "Active",
25
+ "relationship": "coach",
26
+ "_relationship-display": "Coach"
27
+ }
@@ -0,0 +1,26 @@
1
+ {
2
+ "cnt": 1,
3
+ "offset": 0,
4
+ "results": [{
5
+ "id": 98765,
6
+ "coach": {
7
+ "_name": "Coach John",
8
+ "id": 5678,
9
+ "email": "coach@example.com",
10
+ "firstname": "Coach",
11
+ "lastname": "john",
12
+ "isPremium": true
13
+ },
14
+ "client": {
15
+ "_name": "joe athlete",
16
+ "id": 1234,
17
+ "email": "joeathlete@example.com",
18
+ "firstname": "joe",
19
+ "lastname": "athlete"
20
+ },
21
+ "state": "pending_coach",
22
+ "_state-display": "Pending",
23
+ "relationship": "coach",
24
+ "_relationship-display": "Coach"
25
+ }]
26
+ }
@@ -0,0 +1,22 @@
1
+ {
2
+ "id": 8765,
3
+ "coach": {
4
+ "_name": "coach John",
5
+ "id": 5678,
6
+ "email": "coach@example.com",
7
+ "firstname": "Coach",
8
+ "lastname": "John"
9
+ },
10
+ "client": {
11
+ "_name": "joe athlete",
12
+ "id": 1234,
13
+ "email": "joeathlete@example.com",
14
+ "firstname": "joe",
15
+ "lastname": "athlete",
16
+ "isPremium": true
17
+ },
18
+ "state": "pending_coach",
19
+ "_state-display": "Pending",
20
+ "relationship": "coach",
21
+ "_relationship-display": "Coach"
22
+ }
@@ -0,0 +1,14 @@
1
+ {
2
+ "email": "joeathlete@example.com",
3
+ "uuid": "yyyy",
4
+ "firstname": "joe",
5
+ "lastname": "athlete",
6
+ "locale": "English (United States)",
7
+ "timezone": "Etc/UTC",
8
+ "weekStart": "sun",
9
+ "_weekStart-display": "Sunday",
10
+ "stripeId": "xxxx",
11
+ "prefsMask": 0,
12
+ "cls": "net.todaysplan.model.users.User",
13
+ "id": 1234
14
+ }
@@ -2,7 +2,7 @@ require 'spec_helper'
2
2
 
3
3
  describe TodaysPlan::Athlete do
4
4
 
5
- let(:response){File.read("spec/fixtures/athletes/response.json")}
5
+ let(:response){File.read("spec/fixtures/athletes/search_response.json")}
6
6
 
7
7
  it "expect to get all athletes" do
8
8
  stub_request(:get, "#{TodaysPlan.endpoint}/users/delegates/users").
@@ -12,13 +12,13 @@ describe TodaysPlan::Athlete do
12
12
  all = TodaysPlan::Athlete.all()
13
13
  expect(all).to be_a(Array)
14
14
  expect(all[0]).to be_a(TodaysPlan::Athlete)
15
- expect(all[0].first_name).to_not be_nil
16
- expect(all[0].last_name).to_not be_nil
17
- expect(all[0].coach).to_not be_nil
18
- expect(all[0].timezone).to_not be_nil
19
- expect(all[0].id).to_not be_nil
20
- expect(all[0].name).to_not be_nil
21
- expect(all[0].email).to_not be_nil
15
+ expect(all[0].first_name).to eq "Joe"
16
+ expect(all[0].last_name).to eq "Athlete"
17
+ expect(all[0].coach).to eq 7187033
18
+ expect(all[0].timezone).to eq "US/Mountain"
19
+ expect(all[0].id).to eq 7187033
20
+ expect(all[0].name).to eq "Joe Athlete"
21
+ expect(all[0].email).to eq "joeathlete@example.com"
22
22
  end
23
23
 
24
24
  it "expect to get one athlete" do
@@ -38,5 +38,55 @@ describe TodaysPlan::Athlete do
38
38
  expect(athlete).to respond_to(:dob)
39
39
  end
40
40
 
41
+ it "expect to create one athlete" do
42
+ options = {user_email: 'joeathlete@example.com', firstname: 'joe',
43
+ lastname: 'athlete', password:'password', coach_email: 'coach@email.com'}
44
+ # preregister
45
+ stub_request(:get, "#{TodaysPlan.endpoint}/auth/preregister").
46
+ with(:headers => {'Accept'=>'*/*'}).
47
+ to_return(:status => 200, :body => "", :headers => {})
48
+ #register
49
+ stub_request(:post, "#{TodaysPlan.endpoint}/auth/register").
50
+ with(:body => '{"email":"joeathlete@example.com","firstname":"joe","lastname":"athlete","password":"password"}',
51
+ :headers => {'Accept'=>'*/*'}).
52
+ to_return(:status => 200,
53
+ :body => File.read("spec/fixtures/athletes/register_response.json"),
54
+ :headers => {})
55
+ #login as new user
56
+ stub_request(:post, TodaysPlan.endpoint+'/auth/login').
57
+ with(:body => "{\"username\":\"joeathlete@example.com\",\"password\":\"password\",\"token\":true}",
58
+ :headers => {'Accept'=>'application/json',
59
+ 'Content-Type'=>'application/json', }).
60
+ to_return(:status => 200, :body => '{"token":"abc-456"}', :headers => {})
61
+ #invite the coach
62
+ stub_request(:post, "#{TodaysPlan.endpoint}/users/delegates/invite").
63
+ with(:body => '{"email":"coach@email.com","state":"pending_coach","relationship":"coach"}',
64
+ :headers => {'Accept'=>'application/json',
65
+ 'Authorization'=>'Bearer abc-456',
66
+ 'Content-Type'=>'application/json'}).
67
+ to_return(:status => 200,
68
+ :body => File.read("spec/fixtures/athletes/invite_response.json"),
69
+ :headers => {})
70
+ # search for pending invites
71
+ stub_request(:post, "#{TodaysPlan.endpoint}/users/delegates/search/0/100").
72
+ with(:body => '{"state":"pending_coach"}',
73
+ :headers => {'Accept'=>'application/json',
74
+ 'Authorization'=>'Bearer abc-123',
75
+ 'Content-Type'=>'application/json'}).
76
+ to_return(:status => 200,
77
+ :body => File.read("spec/fixtures/athletes/delegates_response.json"),
78
+ :headers => {})
79
+ # accept invite
80
+ stub_request(:get, "#{TodaysPlan.endpoint}/users/delegates/invite/accept/98765").
81
+ with(:headers => {'Accept'=>'application/json', 'Authorization'=>'Bearer abc-123'}).
82
+ to_return(:status => 200,
83
+ :body => File.read("spec/fixtures/athletes/accept_response.json"),
84
+ :headers => {})
85
+ athlete = TodaysPlan::Athlete.create(options)
86
+ expect(athlete.first_name).to eq "joe"
87
+ expect(athlete.last_name).to eq "athlete"
88
+ expect(athlete.email).to eq "joeathlete@example.com"
89
+ expect(athlete.id).to eq(1234)
90
+ end
41
91
 
42
92
  end
@@ -17,25 +17,62 @@ describe TodaysPlan::Connector do
17
17
  end
18
18
 
19
19
  it "expect to create new connect with client" do
20
- client = double(token: 'abc-123')
20
+ client = double(token: 'abc-123', code: 200)
21
21
  expect(TodaysPlan::Client).to_not receive(:new)
22
22
  TodaysPlan::Connector.new("/test", client)
23
23
  end
24
24
 
25
25
  it "expect rest-client get request" do
26
- response = double(body: '{"message":"test"}')
26
+ response = double(body: '{"message":"test"}', code: 200)
27
27
  client = double(token: 'abc-123')
28
28
  expect(TodaysPlan::Client).to receive(:new).with(username, password).and_return(client)
29
29
  expect(RestClient::Request).to receive(:execute).and_return(response)
30
30
  expect(TodaysPlan::Connector.new("/test",).get()).to eq({"message"=>"test"})
31
31
  end
32
+
32
33
  it "expect rest-client post request" do
33
- response = double(body: '{"message":"test"}')
34
+ response = double(body: '{"message":"test"}', code: 201)
34
35
  client = double(token: 'abc-123')
35
36
  expect(TodaysPlan::Client).to receive(:new).with(username, password).and_return(client)
36
37
  expect(RestClient::Request).to receive(:execute).and_return(response)
37
38
  expect(TodaysPlan::Connector.new("/test",).post()).to eq({"message"=>"test"})
38
39
  end
39
40
 
40
-
41
+
42
+ it "expect rest-client post raise error empty body" do
43
+ response = double(body: nil, code: 503)
44
+ client = double(token: 'abc-123')
45
+ expect(TodaysPlan::Client).to receive(:new).with(username, password).and_return(client)
46
+ expect(RestClient::Request).to receive(:execute).and_return(response)
47
+ expect{TodaysPlan::Connector.new("/test",).post()}.to raise_error(TodaysPlan::ServerError)
48
+ end
49
+
50
+ it "expect rest-client get raise error empty body" do
51
+ response = double(body: nil, code: 200)
52
+ client = double(token: 'abc-123')
53
+ expect(TodaysPlan::Client).to receive(:new).with(username, password).and_return(client)
54
+ expect(RestClient::Request).to receive(:execute).and_return(response)
55
+ expect{TodaysPlan::Connector.new("/test",).get()}.to raise_error(TodaysPlan::ServerError)
56
+ end
57
+
58
+ it "expect rest-client get raise error 404" do
59
+ client = double(token: 'abc-123')
60
+ allow(RestClient::NotFound).to receive(:body).and_return('{"message":"testing"}')
61
+ allow(RestClient::NotFound).to receive(:code).and_return(404)
62
+ expect(TodaysPlan::Client).to receive(:new).with(username, password).and_return(client)
63
+ expect(RestClient::Request).to receive(:execute).and_return(RestClient::NotFound)
64
+ expect{TodaysPlan::Connector.new("/test",).get()}.to raise_error(TodaysPlan::NotFoundError)
65
+ end
66
+
67
+ it "expect rest-client get raise error 401" do
68
+ response = double('RestClient::Unauthorized',body: '{}', code: 401)
69
+ client = double(token: 'abc-123')
70
+ expect(TodaysPlan::Client).to receive(:new).with(username, password).and_return(client)
71
+ allow(RestClient::Unauthorized).to receive(:body).and_return('{"message":"testing"}')
72
+ allow(RestClient::Unauthorized).to receive(:code).and_return(401)
73
+ expect(RestClient::Request).to receive(:execute).and_return(RestClient::Unauthorized)
74
+ expect{TodaysPlan::Connector.new("/test",).get()}.to raise_error(TodaysPlan::UnauthorizedError)
75
+ end
76
+
77
+
41
78
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: todaysplan
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.0
4
+ version: 0.2.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Curt Wilhelm
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2017-01-13 00:00:00.000000000 Z
11
+ date: 2017-01-16 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: rest-client
@@ -95,10 +95,15 @@ files:
95
95
  - lib/todays_plan/athlete.rb
96
96
  - lib/todays_plan/client.rb
97
97
  - lib/todays_plan/connector.rb
98
+ - lib/todays_plan/errors.rb
98
99
  - lib/todays_plan/version.rb
99
100
  - spec/fixtures/activities/incomplete.json
100
101
  - spec/fixtures/activities/incomplete_response.json
101
- - spec/fixtures/athletes/response.json
102
+ - spec/fixtures/athletes/accept_response.json
103
+ - spec/fixtures/athletes/delegates_response.json
104
+ - spec/fixtures/athletes/invite_response.json
105
+ - spec/fixtures/athletes/register_response.json
106
+ - spec/fixtures/athletes/search_response.json
102
107
  - spec/spec_helper.rb
103
108
  - spec/todays_plan/activity_spec.rb
104
109
  - spec/todays_plan/athlete_spec.rb
@@ -132,7 +137,11 @@ summary: A Ruby Library for TodaysPlan
132
137
  test_files:
133
138
  - spec/fixtures/activities/incomplete.json
134
139
  - spec/fixtures/activities/incomplete_response.json
135
- - spec/fixtures/athletes/response.json
140
+ - spec/fixtures/athletes/accept_response.json
141
+ - spec/fixtures/athletes/delegates_response.json
142
+ - spec/fixtures/athletes/invite_response.json
143
+ - spec/fixtures/athletes/register_response.json
144
+ - spec/fixtures/athletes/search_response.json
136
145
  - spec/spec_helper.rb
137
146
  - spec/todays_plan/activity_spec.rb
138
147
  - spec/todays_plan/athlete_spec.rb