teachable-stats 0.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.
- checksums.yaml +7 -0
- data/.gitignore +9 -0
- data/.rspec +2 -0
- data/.travis.yml +4 -0
- data/Gemfile +4 -0
- data/README.md +289 -0
- data/Rakefile +6 -0
- data/bin/console +14 -0
- data/bin/setup +7 -0
- data/lib/helpers/configuration.rb +33 -0
- data/lib/teachable/stats.rb +14 -0
- data/lib/teachable/stats/authenticate.rb +28 -0
- data/lib/teachable/stats/get_token.rb +26 -0
- data/lib/teachable/stats/orders_create.rb +45 -0
- data/lib/teachable/stats/orders_destroy.rb +26 -0
- data/lib/teachable/stats/orders_get.rb +22 -0
- data/lib/teachable/stats/signup.rb +26 -0
- data/lib/teachable/stats/users.rb +18 -0
- data/lib/teachable/stats/version.rb +5 -0
- data/notes.md +36 -0
- data/teachable-stats.gemspec +33 -0
- metadata +176 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: 578241224c44c9e3e01e17badc09053f9c5f8fc7
|
4
|
+
data.tar.gz: cbcb16f4c2d68132c5391fd9c71082ea59ca737c
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: 9ffa51e559741b39bbdc20547c16556f41f626d291d9c0a3c5c52704b549db8873c3f013d3fd3e480eaaf184d0d6f58b9ad551dc960579b5c03f1cf829ad6184
|
7
|
+
data.tar.gz: a1b90057a89c02de11be38ff5e3409cc725a9e0b788748872e9a3dc16904758b0abc5c4b6d08538dfb661787c57dba5376fef6cb7fea9d9b6b741c87da6c9338
|
data/.gitignore
ADDED
data/.rspec
ADDED
data/.travis.yml
ADDED
data/Gemfile
ADDED
data/README.md
ADDED
@@ -0,0 +1,289 @@
|
|
1
|
+
# Teachable Stats Gem
|
2
|
+
|
3
|
+
Easy to use and configure gem wrapper for the Teachable API.
|
4
|
+
|
5
|
+
#### Why does the Teachable-Stats gem exist?
|
6
|
+
|
7
|
+
The Teachable::Stats wrapper gem exists to make hitting the Teachable API much easier. No longer do you need to struggle through rest-client or Faraday and constantly send over your user_email and user_token. Now you can just authenticate once with your email and password and hit all the endpoints conveniently!
|
8
|
+
|
9
|
+
#### Installation
|
10
|
+
|
11
|
+
Add this line to your application's Gemfile:
|
12
|
+
|
13
|
+
```ruby
|
14
|
+
gem 'teachable-stats'
|
15
|
+
```
|
16
|
+
|
17
|
+
And then execute:
|
18
|
+
|
19
|
+
$ bundle
|
20
|
+
|
21
|
+
Or install it yourself as:
|
22
|
+
|
23
|
+
$ gem install teachable-stats
|
24
|
+
|
25
|
+
## Usage
|
26
|
+
|
27
|
+
**Registering to the API**
|
28
|
+
In order to use the gem, you first need to register an account with Teachable. You used to have to make a complicated post request directly to Teachable's API via this complicated curl request:
|
29
|
+
|
30
|
+
```bash
|
31
|
+
curl -X POST -d '{ "user": { "email": "valid_email1@example.com", "password": "password" }}' https://fast-bayou-75985.herokuapp.com//users/sign_in.json -i -H "Accept: application/json" -H "Content-Type: application/json"
|
32
|
+
```
|
33
|
+
|
34
|
+
But no longer! After you've included this gem in your Gemfile and run 'bundle', you can register to the Teachable using this much simpler method call:
|
35
|
+
|
36
|
+
```ruby
|
37
|
+
Teachable::Stats.register(email: "new_email@example.com", password: "8LettersLongAtLeast", password_confirmation: "8LettersLongAtLeast")
|
38
|
+
```
|
39
|
+
|
40
|
+
Note the password field has to be at least 8 letters long and the email address cannot already exist in the database.
|
41
|
+
|
42
|
+
**Getting user_token and credentials**
|
43
|
+
If you are an already registered user and simply want your credentials sent back to you, you can simply get your credentials via this .get_token convenience method
|
44
|
+
|
45
|
+
```ruby
|
46
|
+
Teachable::Stats.get_token(email: "registered_email@example.com", password: "validPassword")
|
47
|
+
```
|
48
|
+
|
49
|
+
That will return your credentials, including your token, in this form:
|
50
|
+
|
51
|
+
```
|
52
|
+
{"id"=>36,
|
53
|
+
"name"=>nil,
|
54
|
+
"nickname"=>nil,
|
55
|
+
"image"=>nil,
|
56
|
+
"email"=>"registered_email@example.com",
|
57
|
+
"tokens"=>"-y9s9TyMHdWmniBLfE8i",
|
58
|
+
"created_at"=>"2016-02-14T20:53:19.896Z",
|
59
|
+
"updated_at"=>"2016-02-16T00:00:08.120Z"}
|
60
|
+
```
|
61
|
+
|
62
|
+
Note the returned value of the .get_token method is a ruby hash and it does not show your password. However, it does have your user_token which you need to use to configure your gem.
|
63
|
+
|
64
|
+
**Configuring your gem**
|
65
|
+
You need to set your :user_email and :user_token prior to making API requests to the Teachable API. Configuring your gem simply means providing the gem your registered user email and user_token. There are two ways to do this:
|
66
|
+
|
67
|
+
1. In your application, you can write this code to manually configure your gem:
|
68
|
+
|
69
|
+
```ruby
|
70
|
+
Teachable::Stats.configuration do |config|
|
71
|
+
config.user_email = "your_email@example.com"
|
72
|
+
config.user_token = "some_secure_random_string_goes_here_that_you_can_get_via_the_get_token_method"
|
73
|
+
end
|
74
|
+
```
|
75
|
+
|
76
|
+
Again, the user_email and user_token can be obtained via the .get_token method provided by the gem.
|
77
|
+
|
78
|
+
2. You can also configure your gem using the gem's .authenticate convenience method. This is how you can use the convenience method.
|
79
|
+
|
80
|
+
```ruby
|
81
|
+
Teachable::Stats.authenticate(email: "valid_email1@example.com", password: "password")
|
82
|
+
```
|
83
|
+
|
84
|
+
Give that above method a try! That email and password are valid. You should see something like this return:
|
85
|
+
|
86
|
+
```
|
87
|
+
"Logged in as user: valid_email1@example.com with token: -y9s9TyMHdWmniBLfE8i"
|
88
|
+
```
|
89
|
+
|
90
|
+
Behind the scenes, that sets the class variables called user_email and user_token to the email and user_token that are shown in the string. All you need to provide to the authenticate convenience method are your already registered and valid email and password. That's it!
|
91
|
+
|
92
|
+
## Making queries to the Teachable API
|
93
|
+
|
94
|
+
Once you've registered and authenticated, you an start making queries to the API. Currently, the Teachable API has 4 endpoints:
|
95
|
+
|
96
|
+
1. Users#get
|
97
|
+
2. Orders#get
|
98
|
+
3. Orders#post
|
99
|
+
4. Orders#destroy
|
100
|
+
|
101
|
+
Let's see how to make requests to all 4!
|
102
|
+
|
103
|
+
**Users#get**
|
104
|
+
```ruby
|
105
|
+
Teachable::Stats.get_user
|
106
|
+
```
|
107
|
+
|
108
|
+
**Orders*get**
|
109
|
+
```ruby
|
110
|
+
Teachable::Stats.get_orders
|
111
|
+
```
|
112
|
+
|
113
|
+
**Orders*post**
|
114
|
+
```ruby
|
115
|
+
Teachable::Stats.create_my_order(number: 1, total: 2.0, total_quantity: 3, email: "valid_email1@example.com")
|
116
|
+
```
|
117
|
+
|
118
|
+
In the above convenience method for creating_orders, you currently need to provide your registered email. However, in future versions we will likely take this away since your are currently authenticated by this point.
|
119
|
+
|
120
|
+
The above method will create an order for the authenticated user. See this:
|
121
|
+
|
122
|
+
```ruby
|
123
|
+
Teachable::Stats.destroy_my_order(order_id: 2)
|
124
|
+
```
|
125
|
+
|
126
|
+
The above convenience method will destroy an order for the currently authenticated user. The order destroyed order will be the one that has an :id equal to the order_id provided to the method.
|
127
|
+
|
128
|
+
|
129
|
+
#### Examples
|
130
|
+
|
131
|
+
```ruby
|
132
|
+
Teachable::Stats.register(email: "newly_registered_email@example.com", password: "new_password", password_confirmation: "new_password")
|
133
|
+
```
|
134
|
+
|
135
|
+
```
|
136
|
+
=> {"id"=>41,
|
137
|
+
"name"=>nil,
|
138
|
+
"nickname"=>nil,
|
139
|
+
"image"=>nil,
|
140
|
+
"email"=>"newly_registered_email@example.com",
|
141
|
+
"tokens"=>"jXVrTVgt9UQmLYGe2f8P",
|
142
|
+
"created_at"=>"2016-02-16T06:00:46.784Z",
|
143
|
+
"updated_at"=>"2016-02-16T06:00:46.806Z"}
|
144
|
+
```
|
145
|
+
|
146
|
+
```ruby
|
147
|
+
Teachable::Stats.get_token(email: "newly_registered_email@example.com", password: "new_password")
|
148
|
+
```
|
149
|
+
|
150
|
+
```
|
151
|
+
=> {"id"=>41,
|
152
|
+
"name"=>nil,
|
153
|
+
"nickname"=>nil,
|
154
|
+
"image"=>nil,
|
155
|
+
"email"=>"newly_registered_email@example.com",
|
156
|
+
"tokens"=>"jXVrTVgt9UQmLYGe2f8P",
|
157
|
+
"created_at"=>"2016-02-16T06:00:46.784Z",
|
158
|
+
"updated_at"=>"2016-02-16T06:02:09.474Z"}
|
159
|
+
```
|
160
|
+
|
161
|
+
At this point, the .user_email and .user_token getters are still unset
|
162
|
+
```
|
163
|
+
Teachable::Stats.user_email
|
164
|
+
=> nil
|
165
|
+
|
166
|
+
Teachable::Stats.user_token
|
167
|
+
=> nil
|
168
|
+
```
|
169
|
+
|
170
|
+
Let's set the user_token and user_email via the authenticate convenience method.
|
171
|
+
|
172
|
+
```ruby
|
173
|
+
Teachable::Stats.authenticate(email: "newly_registered_email@example.com", password: "new_password")
|
174
|
+
```
|
175
|
+
|
176
|
+
```
|
177
|
+
=> "Logged in as user: newly_registered_email@example.com with token: jXVrTVgt9UQmLYGe2f8P"
|
178
|
+
```
|
179
|
+
|
180
|
+
We can see that the getter convenience methods are now set.
|
181
|
+
|
182
|
+
```ruby
|
183
|
+
Teachable::Stats.user_email
|
184
|
+
=> "newly_registered_email@example.com"
|
185
|
+
[8] pry(main)> Teachable::Stats.user_token
|
186
|
+
=> "jXVrTVgt9UQmLYGe2f8P"
|
187
|
+
```
|
188
|
+
|
189
|
+
Now we can freely access the API:
|
190
|
+
|
191
|
+
Let's get the orders for the current authenticated user. There should be none:
|
192
|
+
|
193
|
+
```ruby
|
194
|
+
Teachable::Stats.get_orders
|
195
|
+
```
|
196
|
+
|
197
|
+
```
|
198
|
+
=> []
|
199
|
+
```
|
200
|
+
|
201
|
+
Let's try to get the current authenticated user.
|
202
|
+
|
203
|
+
```ruby
|
204
|
+
Teachable::Stats.get_user
|
205
|
+
```
|
206
|
+
|
207
|
+
```
|
208
|
+
Teachable::Stats.get_user
|
209
|
+
=> {"id"=>41,
|
210
|
+
"name"=>nil,
|
211
|
+
"nickname"=>nil,
|
212
|
+
"image"=>nil,
|
213
|
+
"email"=>"newly_registered_email@example.com",
|
214
|
+
"tokens"=>"jXVrTVgt9UQmLYGe2f8P",
|
215
|
+
"created_at"=>"2016-02-16T06:00:46.784Z",
|
216
|
+
"updated_at"=>"2016-02-16T06:05:01.396Z"}
|
217
|
+
```
|
218
|
+
|
219
|
+
Let's create an order:
|
220
|
+
|
221
|
+
```ruby
|
222
|
+
Teachable::Stats.create_my_order(number:1, total:2, total_quantity:3, email:"newly_registered_email@example.com")
|
223
|
+
```
|
224
|
+
|
225
|
+
```
|
226
|
+
=> [{"id"=>140,
|
227
|
+
"number"=>"e333b0d103f5ce52",
|
228
|
+
"total"=>"2.0",
|
229
|
+
"total_quantity"=>3,
|
230
|
+
"email"=>"newly_registered_email@example.com",
|
231
|
+
"special_instructions"=>"special instructions foo bar",
|
232
|
+
"created_at"=>"2016-02-16T06:06:24.710Z",
|
233
|
+
"updated_at"=>"2016-02-16T06:06:24.710Z"}]
|
234
|
+
```
|
235
|
+
|
236
|
+
Let's check to see if that order was created.
|
237
|
+
|
238
|
+
```ruby
|
239
|
+
Teachable::Stats.get_orders
|
240
|
+
```
|
241
|
+
|
242
|
+
```
|
243
|
+
=> [{"id"=>140,
|
244
|
+
"number"=>"e333b0d103f5ce52",
|
245
|
+
"total"=>"2.0",
|
246
|
+
"total_quantity"=>3,
|
247
|
+
"email"=>"newly_registered_email@example.com",
|
248
|
+
"special_instructions"=>"special instructions foo bar",
|
249
|
+
"created_at"=>"2016-02-16T06:06:24.710Z",
|
250
|
+
"updated_at"=>"2016-02-16T06:06:24.710Z"}]
|
251
|
+
```
|
252
|
+
|
253
|
+
Let's destroy that order:
|
254
|
+
|
255
|
+
```ruby
|
256
|
+
Teachable::Stats.destroy_my_order(order_id:140)
|
257
|
+
```
|
258
|
+
|
259
|
+
```
|
260
|
+
=> "Order with id: 140 deleted."
|
261
|
+
```
|
262
|
+
|
263
|
+
We should no longer have any orders associated with this user:
|
264
|
+
|
265
|
+
```ruby
|
266
|
+
Teachable::Stats.get_orders
|
267
|
+
```
|
268
|
+
|
269
|
+
```
|
270
|
+
=> []
|
271
|
+
```
|
272
|
+
|
273
|
+
Mad easy right?
|
274
|
+
|
275
|
+
## Development
|
276
|
+
|
277
|
+
After checking out the repo, run `bin/setup` to install dependencies. Then, run `rake spec` to run the tests. You can also run `bin/console` for an interactive prompt that will allow you to experiment.
|
278
|
+
|
279
|
+
To install this gem onto your local machine, run `bundle exec rake install`. To release a new version, update the version number in `version.rb`, and then run `bundle exec rake release`, which will create a git tag for the version, push git commits and tags, and push the `.gem` file to [rubygems.org](https://rubygems.org).
|
280
|
+
|
281
|
+
## Contributing
|
282
|
+
|
283
|
+
Bug reports and pull requests are welcome on GitHub at https://github.com/[USERNAME]/teachable-stats.
|
284
|
+
|
285
|
+
Many thanks to the development team:
|
286
|
+
- Jeffrey Wan
|
287
|
+
- Noah Pryor
|
288
|
+
- Dustin Eichler
|
289
|
+
- The kind folks at Teachable!
|
data/Rakefile
ADDED
data/bin/console
ADDED
@@ -0,0 +1,14 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
|
3
|
+
require "bundler/setup"
|
4
|
+
require "teachable/stats"
|
5
|
+
|
6
|
+
# You can add fixtures and/or initialization code here to make experimenting
|
7
|
+
# with your gem easier. You can also use a different console, if you like.
|
8
|
+
|
9
|
+
# (If you use this, don't forget to add pry to your Gemfile!)
|
10
|
+
# require "pry"
|
11
|
+
# Pry.start
|
12
|
+
|
13
|
+
require "irb"
|
14
|
+
IRB.start
|
data/bin/setup
ADDED
@@ -0,0 +1,33 @@
|
|
1
|
+
|
2
|
+
module Configuration
|
3
|
+
def configuration
|
4
|
+
yield self
|
5
|
+
end
|
6
|
+
|
7
|
+
def define_setting(name, default = nil)
|
8
|
+
#this sets a class variable
|
9
|
+
class_variable_set("@@#{name}", default)
|
10
|
+
|
11
|
+
#this defines a class level setter
|
12
|
+
define_class_method("#{name}=") do |value|
|
13
|
+
class_variable_set("@@#{name}", value)
|
14
|
+
end
|
15
|
+
|
16
|
+
#this defines a class level getter
|
17
|
+
define_class_method(name) do
|
18
|
+
class_variable_get("@@#{name}")
|
19
|
+
end
|
20
|
+
end
|
21
|
+
|
22
|
+
private
|
23
|
+
|
24
|
+
# 1. we are opening up the singleton class/metaclass only in order to retrieve "self"
|
25
|
+
# 2. next, we are calling instance_eval to define a method on the self which is whatever class we
|
26
|
+
# include this module in.
|
27
|
+
# 3. The &block, due to the ampersand, refers to the block we pass to the define_class_method method.j
|
28
|
+
def define_class_method(name, &block)
|
29
|
+
(class << self; self; end).instance_eval do
|
30
|
+
define_method name, &block
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
@@ -0,0 +1,14 @@
|
|
1
|
+
require "teachable/stats/version"
|
2
|
+
require "helpers/configuration"
|
3
|
+
require 'open-uri'
|
4
|
+
require 'rest-client'
|
5
|
+
Dir["./lib/teachable/stats/*.rb"].each {|file| require file }
|
6
|
+
|
7
|
+
module Teachable
|
8
|
+
module Stats
|
9
|
+
extend Configuration
|
10
|
+
|
11
|
+
define_setting :user_email
|
12
|
+
define_setting :user_token
|
13
|
+
end
|
14
|
+
end
|
@@ -0,0 +1,28 @@
|
|
1
|
+
require './lib/teachable/stats'
|
2
|
+
|
3
|
+
module Teachable
|
4
|
+
module Stats
|
5
|
+
def self.authenticate(email:, password:)
|
6
|
+
begin
|
7
|
+
user_credentials = get_token(email: email, password: password)
|
8
|
+
raise RegistrationError if failed_authentication?(user_credentials)
|
9
|
+
self.user_email, self.user_token = user_credentials["email"], user_credentials["tokens"]
|
10
|
+
"Logged in as user: #{self.user_email} with token: #{self.user_token}"
|
11
|
+
rescue => e
|
12
|
+
if e.class == RegistrationError
|
13
|
+
"#{e.message}"
|
14
|
+
else
|
15
|
+
errors = JSON.parse(e.response)
|
16
|
+
errors_formatted = errors["error"]
|
17
|
+
"Something went wrong when trying to register. These are your errors: #{errors_formatted}"
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
21
|
+
|
22
|
+
private
|
23
|
+
|
24
|
+
def self.failed_authentication?(response)
|
25
|
+
response =~ /Invalid email or password/
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
@@ -0,0 +1,26 @@
|
|
1
|
+
require './lib/teachable/stats'
|
2
|
+
|
3
|
+
module Teachable
|
4
|
+
module Stats
|
5
|
+
def self.get_token(email:, password:)
|
6
|
+
begin
|
7
|
+
base_url = "https://fast-bayou-75985.herokuapp.com/users/sign_in.json"
|
8
|
+
header = { accept: :json }
|
9
|
+
response = RestClient.post base_url,
|
10
|
+
{ "user": {
|
11
|
+
"email": email,
|
12
|
+
"password": password
|
13
|
+
}
|
14
|
+
},
|
15
|
+
header
|
16
|
+
JSON.parse(response.body)
|
17
|
+
rescue => e
|
18
|
+
if e.class == RestClient::Unauthorized
|
19
|
+
errors = JSON.parse(e.response)
|
20
|
+
errors_formatted = errors["error"]
|
21
|
+
"Something went wrong when trying to get your user info and token. These are your errors: #{errors_formatted}"
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
@@ -0,0 +1,45 @@
|
|
1
|
+
require './lib/teachable/stats'
|
2
|
+
|
3
|
+
module Teachable
|
4
|
+
module Stats
|
5
|
+
def self.create_my_order(number: 1, total:, total_quantity:, email:)
|
6
|
+
begin
|
7
|
+
base_url = "https://fast-bayou-75985.herokuapp.com/api/orders.json"
|
8
|
+
response_total_orders = []
|
9
|
+
number.times do
|
10
|
+
response_total_orders << (RestClient.post base_url,
|
11
|
+
{ order: {
|
12
|
+
total: total,
|
13
|
+
total_quantity: total_quantity,
|
14
|
+
email: email,
|
15
|
+
special_instructions: "special instructions foo bar"
|
16
|
+
}
|
17
|
+
},
|
18
|
+
params: { user_email: self.user_email,
|
19
|
+
user_token: self.user_token
|
20
|
+
})
|
21
|
+
end
|
22
|
+
response_total_orders.map do |response|
|
23
|
+
JSON.parse(response.body)
|
24
|
+
end
|
25
|
+
rescue => e
|
26
|
+
if e.class == RestClient::Unauthorized
|
27
|
+
errors = JSON.parse(e.response)
|
28
|
+
errors["error"]
|
29
|
+
else
|
30
|
+
errors = JSON.parse(e.response)
|
31
|
+
errors_formatted = errors["errors"].to_s + errors["error"].to_s
|
32
|
+
"Something went wrong when trying to create that order. These are your errors: #{errors_formatted}"
|
33
|
+
end
|
34
|
+
end
|
35
|
+
end
|
36
|
+
end
|
37
|
+
end
|
38
|
+
|
39
|
+
|
40
|
+
=begin
|
41
|
+
invalid_arguments = order_create_invalid_args(number, total, total_quantity, email)
|
42
|
+
order_create_invalid_message = "These order create arguments are invalid: #{invalid_arguments}"
|
43
|
+
raise ArgumentError, order_create_invalid_message, unless order_params_valid?(number, total, total_quantity, email)
|
44
|
+
|
45
|
+
=end
|
@@ -0,0 +1,26 @@
|
|
1
|
+
require './lib/teachable/stats'
|
2
|
+
|
3
|
+
module Teachable
|
4
|
+
module Stats
|
5
|
+
def self.destroy_my_order(order_id: )
|
6
|
+
begin
|
7
|
+
base_url = "https://fast-bayou-75985.herokuapp.com/api/orders/#{order_id}.json"
|
8
|
+
response = RestClient.delete base_url,
|
9
|
+
params: { user_email: self.user_email,
|
10
|
+
user_token: self.user_token
|
11
|
+
}
|
12
|
+
"Order with id: #{order_id} deleted." if response == ""
|
13
|
+
rescue => e
|
14
|
+
if e.class == RestClient::Unauthorized
|
15
|
+
errors = JSON.parse(e.response)
|
16
|
+
errors_formatted = errors["error"]
|
17
|
+
"#{errors_formatted}"
|
18
|
+
else
|
19
|
+
errors = JSON.parse(e.response)
|
20
|
+
errors_formatted = "That order_id does not exist" if errors["error"] == "Not Found"
|
21
|
+
"Something went wrong when trying to delete that order. These are your errors: #{errors_formatted}"
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
@@ -0,0 +1,22 @@
|
|
1
|
+
require './lib/teachable/stats'
|
2
|
+
|
3
|
+
module Teachable
|
4
|
+
module Stats
|
5
|
+
def self.get_orders
|
6
|
+
begin
|
7
|
+
base_url = "https://fast-bayou-75985.herokuapp.com/api/orders.json"
|
8
|
+
header = { accept: :json }
|
9
|
+
response = RestClient.get base_url,
|
10
|
+
params: {
|
11
|
+
user_email: self.user_email,
|
12
|
+
user_token: self.user_token
|
13
|
+
}
|
14
|
+
JSON.parse(response.body)
|
15
|
+
rescue => e
|
16
|
+
errors = JSON.parse(e.response)
|
17
|
+
errors_formatted = errors["error"]
|
18
|
+
"#{errors_formatted}"
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
@@ -0,0 +1,26 @@
|
|
1
|
+
require './lib/teachable/stats'
|
2
|
+
|
3
|
+
module Teachable
|
4
|
+
module Stats
|
5
|
+
def self.register(email: , password:, password_confirmation:)
|
6
|
+
begin
|
7
|
+
base_url = "https://fast-bayou-75985.herokuapp.com/users.json"
|
8
|
+
header = { accept: :json }
|
9
|
+
response = RestClient.post base_url,
|
10
|
+
{ "user" => { "email": email,
|
11
|
+
"password": password,
|
12
|
+
"password_confirmation": password_confirmation
|
13
|
+
}
|
14
|
+
},
|
15
|
+
header
|
16
|
+
JSON.parse(response.body)
|
17
|
+
rescue => e
|
18
|
+
errors = JSON.parse(e.response)
|
19
|
+
errors_formatted = errors["errors"].map do |error|
|
20
|
+
error[0] + " " + error[1][0]
|
21
|
+
end.join(", ")
|
22
|
+
"Something went wrong when trying to register. These are your errors: #{errors_formatted}"
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
@@ -0,0 +1,18 @@
|
|
1
|
+
require './lib/teachable/stats'
|
2
|
+
|
3
|
+
module Teachable
|
4
|
+
module Stats
|
5
|
+
def self.get_user
|
6
|
+
begin
|
7
|
+
base_url = "https://fast-bayou-75985.herokuapp.com/api/users/current_user/edit.json"
|
8
|
+
response = RestClient.get base_url, params: { user_email: self.user_email,
|
9
|
+
user_token: self.user_token }
|
10
|
+
JSON.parse(response.body)
|
11
|
+
rescue => e
|
12
|
+
errors = JSON.parse(e.response)
|
13
|
+
errors_formatted = errors["error"]
|
14
|
+
"Something went wrong when trying to get your user info. These are your errors: #{errors_formatted}"
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
data/notes.md
ADDED
@@ -0,0 +1,36 @@
|
|
1
|
+
## Some design choices
|
2
|
+
|
3
|
+
I think the design of this gem was heavily influenced by these links:
|
4
|
+
[configuration module](https://viget.com/extend/easy-gem-configuration-variables-with-defaults)
|
5
|
+
|
6
|
+
I include the Configuration model for the times when the user's configuration changes at runtime.
|
7
|
+
|
8
|
+
I wrote the method signatures with keyword arguments because I'm all about that life (it sincerity, it does 3 things for us:
|
9
|
+
1. allows us to see what the names of the arguments are without having to read the method of the body.
|
10
|
+
2. reduces boiletplate code for extracting hash options.
|
11
|
+
3. The caling method is syntactically equal to calling a method with hash options.)
|
12
|
+
|
13
|
+
-the email parameter in create_order is probably redundant or at least unclear. Do we want the behavior to be that only a user can create orders only for himself or for other users? I assume we only want users to create their own orders. IF that's the case, then I think the email parameter is redundant and perhaps behavior we don't want.
|
14
|
+
- the number column when create a new order is a random string of letters. I took the liberty in interpreting number as just the number of orders to create with the specific parameters of total, total_quantity, and the associated email. For example:
|
15
|
+
|
16
|
+
This curl request:
|
17
|
+
```
|
18
|
+
curl -X POST -d '{ "order": { "total": "2", "total_quantity": "1", "email": "valid_email1@example.com", "special_instructions": "special instructions foo bar" } }' 'https://fast-bayou-75985.herokuapp.com/api/orders.json?user_email=valid_email1@example.com&user_token=-y9s9TyMHdWmniBLfE8i' -i -H "Accept: application/json" -H "Content-Type: application/json"
|
19
|
+
```
|
20
|
+
|
21
|
+
results in:
|
22
|
+
|
23
|
+
```
|
24
|
+
{"id":65,"number":"699dc850250c6ded","total":"2.0","total_quantity":1,"email":"valid_email1@example.com","special_instructions":"special instructions foo bar","created_at":"2016-02-15T19:09:04.478Z","updated_at":"2016-02-15T19:09:04.478Z"}
|
25
|
+
```
|
26
|
+
|
27
|
+
and that number is an odd field. What is that supposed to be anyway?
|
28
|
+
|
29
|
+
I have some helper methods in my spec_helper... where should they go?
|
30
|
+
I was thinking of putting them in spec/helpers... but I actually put a test that tests my helper methods in there. So where should helper methods for my specs actually go? I feel like I misused some folders...
|
31
|
+
|
32
|
+
|
33
|
+
### teardown
|
34
|
+
.delete_all_orders_of_current_user is in the spec_helper and it cleares all the orders associated with the current user.
|
35
|
+
|
36
|
+
Ideally I'd also like to delete the users I created in my tests that register new users, but I currently cannot.
|
@@ -0,0 +1,33 @@
|
|
1
|
+
# coding: utf-8
|
2
|
+
lib = File.expand_path('../lib', __FILE__)
|
3
|
+
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
4
|
+
require 'teachable/stats/version'
|
5
|
+
|
6
|
+
Gem::Specification.new do |spec|
|
7
|
+
spec.name = "teachable-stats"
|
8
|
+
spec.version = Teachable::Stats::VERSION
|
9
|
+
spec.authors = ["Jeffrey Wan"]
|
10
|
+
spec.email = ["Jwan622@gmail.com"]
|
11
|
+
|
12
|
+
spec.summary = %q{This is a wrapper for the mock Teachable API}
|
13
|
+
spec.description = %q{The teachable-stats gem is a wrapper for the Teachable API. Hopefully this saves you time!}
|
14
|
+
spec.homepage = "https://github.com/Jwan622/teachable_challenge_gem/blob/master/lib/teachable/stats.rb"
|
15
|
+
|
16
|
+
# Prevent pushing this gem to RubyGems.org by setting 'allowed_push_host', or
|
17
|
+
# delete this section to allow pushing this gem to any host.
|
18
|
+
|
19
|
+
spec.files = `git ls-files -z`.split("\x0").reject { |f| f.match(%r{^(test|spec|features)/}) }
|
20
|
+
spec.bindir = "exe"
|
21
|
+
spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
|
22
|
+
spec.require_paths = ["lib"]
|
23
|
+
|
24
|
+
spec.add_development_dependency "bundler", "~> 1.10"
|
25
|
+
spec.add_development_dependency "rake", "~> 10.0"
|
26
|
+
spec.add_development_dependency "webmock"
|
27
|
+
spec.add_development_dependency "vcr"
|
28
|
+
spec.add_development_dependency "rspec"
|
29
|
+
spec.add_development_dependency "pry"
|
30
|
+
|
31
|
+
spec.add_dependency "rest-client"
|
32
|
+
spec.add_dependency "json"
|
33
|
+
end
|
metadata
ADDED
@@ -0,0 +1,176 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: teachable-stats
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.1.0
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Jeffrey Wan
|
8
|
+
autorequire:
|
9
|
+
bindir: exe
|
10
|
+
cert_chain: []
|
11
|
+
date: 2016-02-16 00:00:00.000000000 Z
|
12
|
+
dependencies:
|
13
|
+
- !ruby/object:Gem::Dependency
|
14
|
+
name: bundler
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
16
|
+
requirements:
|
17
|
+
- - "~>"
|
18
|
+
- !ruby/object:Gem::Version
|
19
|
+
version: '1.10'
|
20
|
+
type: :development
|
21
|
+
prerelease: false
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
23
|
+
requirements:
|
24
|
+
- - "~>"
|
25
|
+
- !ruby/object:Gem::Version
|
26
|
+
version: '1.10'
|
27
|
+
- !ruby/object:Gem::Dependency
|
28
|
+
name: rake
|
29
|
+
requirement: !ruby/object:Gem::Requirement
|
30
|
+
requirements:
|
31
|
+
- - "~>"
|
32
|
+
- !ruby/object:Gem::Version
|
33
|
+
version: '10.0'
|
34
|
+
type: :development
|
35
|
+
prerelease: false
|
36
|
+
version_requirements: !ruby/object:Gem::Requirement
|
37
|
+
requirements:
|
38
|
+
- - "~>"
|
39
|
+
- !ruby/object:Gem::Version
|
40
|
+
version: '10.0'
|
41
|
+
- !ruby/object:Gem::Dependency
|
42
|
+
name: webmock
|
43
|
+
requirement: !ruby/object:Gem::Requirement
|
44
|
+
requirements:
|
45
|
+
- - ">="
|
46
|
+
- !ruby/object:Gem::Version
|
47
|
+
version: '0'
|
48
|
+
type: :development
|
49
|
+
prerelease: false
|
50
|
+
version_requirements: !ruby/object:Gem::Requirement
|
51
|
+
requirements:
|
52
|
+
- - ">="
|
53
|
+
- !ruby/object:Gem::Version
|
54
|
+
version: '0'
|
55
|
+
- !ruby/object:Gem::Dependency
|
56
|
+
name: vcr
|
57
|
+
requirement: !ruby/object:Gem::Requirement
|
58
|
+
requirements:
|
59
|
+
- - ">="
|
60
|
+
- !ruby/object:Gem::Version
|
61
|
+
version: '0'
|
62
|
+
type: :development
|
63
|
+
prerelease: false
|
64
|
+
version_requirements: !ruby/object:Gem::Requirement
|
65
|
+
requirements:
|
66
|
+
- - ">="
|
67
|
+
- !ruby/object:Gem::Version
|
68
|
+
version: '0'
|
69
|
+
- !ruby/object:Gem::Dependency
|
70
|
+
name: rspec
|
71
|
+
requirement: !ruby/object:Gem::Requirement
|
72
|
+
requirements:
|
73
|
+
- - ">="
|
74
|
+
- !ruby/object:Gem::Version
|
75
|
+
version: '0'
|
76
|
+
type: :development
|
77
|
+
prerelease: false
|
78
|
+
version_requirements: !ruby/object:Gem::Requirement
|
79
|
+
requirements:
|
80
|
+
- - ">="
|
81
|
+
- !ruby/object:Gem::Version
|
82
|
+
version: '0'
|
83
|
+
- !ruby/object:Gem::Dependency
|
84
|
+
name: pry
|
85
|
+
requirement: !ruby/object:Gem::Requirement
|
86
|
+
requirements:
|
87
|
+
- - ">="
|
88
|
+
- !ruby/object:Gem::Version
|
89
|
+
version: '0'
|
90
|
+
type: :development
|
91
|
+
prerelease: false
|
92
|
+
version_requirements: !ruby/object:Gem::Requirement
|
93
|
+
requirements:
|
94
|
+
- - ">="
|
95
|
+
- !ruby/object:Gem::Version
|
96
|
+
version: '0'
|
97
|
+
- !ruby/object:Gem::Dependency
|
98
|
+
name: rest-client
|
99
|
+
requirement: !ruby/object:Gem::Requirement
|
100
|
+
requirements:
|
101
|
+
- - ">="
|
102
|
+
- !ruby/object:Gem::Version
|
103
|
+
version: '0'
|
104
|
+
type: :runtime
|
105
|
+
prerelease: false
|
106
|
+
version_requirements: !ruby/object:Gem::Requirement
|
107
|
+
requirements:
|
108
|
+
- - ">="
|
109
|
+
- !ruby/object:Gem::Version
|
110
|
+
version: '0'
|
111
|
+
- !ruby/object:Gem::Dependency
|
112
|
+
name: json
|
113
|
+
requirement: !ruby/object:Gem::Requirement
|
114
|
+
requirements:
|
115
|
+
- - ">="
|
116
|
+
- !ruby/object:Gem::Version
|
117
|
+
version: '0'
|
118
|
+
type: :runtime
|
119
|
+
prerelease: false
|
120
|
+
version_requirements: !ruby/object:Gem::Requirement
|
121
|
+
requirements:
|
122
|
+
- - ">="
|
123
|
+
- !ruby/object:Gem::Version
|
124
|
+
version: '0'
|
125
|
+
description: The teachable-stats gem is a wrapper for the Teachable API. Hopefully
|
126
|
+
this saves you time!
|
127
|
+
email:
|
128
|
+
- Jwan622@gmail.com
|
129
|
+
executables: []
|
130
|
+
extensions: []
|
131
|
+
extra_rdoc_files: []
|
132
|
+
files:
|
133
|
+
- ".gitignore"
|
134
|
+
- ".rspec"
|
135
|
+
- ".travis.yml"
|
136
|
+
- Gemfile
|
137
|
+
- README.md
|
138
|
+
- Rakefile
|
139
|
+
- bin/console
|
140
|
+
- bin/setup
|
141
|
+
- lib/helpers/configuration.rb
|
142
|
+
- lib/teachable/stats.rb
|
143
|
+
- lib/teachable/stats/authenticate.rb
|
144
|
+
- lib/teachable/stats/get_token.rb
|
145
|
+
- lib/teachable/stats/orders_create.rb
|
146
|
+
- lib/teachable/stats/orders_destroy.rb
|
147
|
+
- lib/teachable/stats/orders_get.rb
|
148
|
+
- lib/teachable/stats/signup.rb
|
149
|
+
- lib/teachable/stats/users.rb
|
150
|
+
- lib/teachable/stats/version.rb
|
151
|
+
- notes.md
|
152
|
+
- teachable-stats.gemspec
|
153
|
+
homepage: https://github.com/Jwan622/teachable_challenge_gem/blob/master/lib/teachable/stats.rb
|
154
|
+
licenses: []
|
155
|
+
metadata: {}
|
156
|
+
post_install_message:
|
157
|
+
rdoc_options: []
|
158
|
+
require_paths:
|
159
|
+
- lib
|
160
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
161
|
+
requirements:
|
162
|
+
- - ">="
|
163
|
+
- !ruby/object:Gem::Version
|
164
|
+
version: '0'
|
165
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
166
|
+
requirements:
|
167
|
+
- - ">="
|
168
|
+
- !ruby/object:Gem::Version
|
169
|
+
version: '0'
|
170
|
+
requirements: []
|
171
|
+
rubyforge_project:
|
172
|
+
rubygems_version: 2.5.2
|
173
|
+
signing_key:
|
174
|
+
specification_version: 4
|
175
|
+
summary: This is a wrapper for the mock Teachable API
|
176
|
+
test_files: []
|