typekitable 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.
@@ -0,0 +1,151 @@
1
+ require 'spec_helper'
2
+
3
+ module Typekitable
4
+ describe Request do
5
+ let(:path) { "kits" }
6
+ let(:verb) { "GET" }
7
+ let(:parameters) { {} }
8
+ let(:token) { "5e4ce50b7c5b996b2fb5e65ee4a6b870b9bd3297" }
9
+
10
+ subject { described_class.new(path, verb, parameters) }
11
+
12
+ context ".new" do
13
+ it "stores the path" do
14
+ expect(subject.verb).to eq(verb)
15
+ end
16
+
17
+ it "stores the verb" do
18
+ expect(subject.path).to eq(path)
19
+ end
20
+
21
+ it "stores the parameters" do
22
+ expect(subject.parameters).to eq(parameters)
23
+ end
24
+ end
25
+
26
+ context ".token" do
27
+ it "returns the token" do
28
+ expect(Tokenizer).to receive(:get_token).and_return(token)
29
+
30
+ subject.token
31
+ end
32
+ end
33
+
34
+ context ".response" do
35
+ context "get kit list" do
36
+ context "successful response" do
37
+ it "returns the request response with access to the code, message, and body" do
38
+ VCR.use_cassette 'kits' do
39
+ allow(subject).to receive(:token).and_return(token)
40
+ @response = subject.response
41
+ end
42
+
43
+ expected_code = "200"
44
+ expected_message = "OK"
45
+ expected_body = "{\"kits\":[{\"id\":\"yuw0tqs\",\"link\":\"/api/v1/json/kits/yuw0tqs\"}]}"
46
+ expect(@response.body).to eq(expected_body)
47
+ expect(@response.code).to eq(expected_code)
48
+ expect(@response.message).to eq(expected_message)
49
+ end
50
+ end
51
+
52
+ context "unsuccessful response" do
53
+ let(:token) { "143250b7c5b996b2fb5e65ee4a6b870b9bd3297" }
54
+
55
+ it "returns the request response with access to the code, message, and body" do
56
+
57
+ VCR.use_cassette 'kits_error' do
58
+ allow(subject).to receive(:token).and_return(token)
59
+ @response = subject.response
60
+ end
61
+
62
+ expected_code = "401"
63
+ expected_message = "Unauthorized"
64
+ expected_body = "{\"errors\":[\"Not authorized\"]}"
65
+ expect(@response.body).to eq(expected_body)
66
+ expect(@response.code).to eq(expected_code)
67
+ expect(@response.message).to eq(expected_message)
68
+ end
69
+ end
70
+ end
71
+
72
+ context "get libraries list" do
73
+ let(:path) { "libraries" }
74
+ let(:verb) { "GET" }
75
+ context "successful response" do
76
+ it "returns the request response with access to the code, message, and body" do
77
+ VCR.use_cassette 'libraries' do
78
+ allow(subject).to receive(:token).and_return(token)
79
+ @response = subject.response
80
+ end
81
+
82
+ expected_code = "200"
83
+ expected_message = "OK"
84
+ expected_body = "{\"libraries\":[{\"id\":\"trial\",\"link\":\"/api/v1/json/libraries/trial\",\"name\":\"Trial Library\"},{\"id\":\"personal\",\"link\":\"/api/v1/json/libraries/personal\",\"name\":\"Personal Library\"},{\"id\":\"full\",\"link\":\"/api/v1/json/libraries/full\",\"name\":\"Full Library\"}]}"
85
+ expect(@response.body).to eq(expected_body)
86
+ expect(@response.code).to eq(expected_code)
87
+ expect(@response.message).to eq(expected_message)
88
+ end
89
+ end
90
+ end
91
+
92
+ context "post new kit" do
93
+ let(:path) { "kits" }
94
+ let(:verb) { "POST" }
95
+ let(:parameters) { {:name => "A new kit", :domains => "http://persazula.com"} }
96
+
97
+ context "successful response" do
98
+ it "returns the request response with access to the code, message, and body" do
99
+ VCR.use_cassette 'add_kit' do
100
+ allow(subject).to receive(:token).and_return(token)
101
+ @response = subject.response
102
+ end
103
+
104
+ expected_code = "200"
105
+ expected_message = "OK"
106
+ expected_body = "{\"kit\":{\"id\":\"fla3cfh\",\"name\":\"A new kit\",\"analytics\":false,\"domains\":[\"persazula.com\"],\"families\":[]}}"
107
+ expect(@response.body).to eq(expected_body)
108
+ expect(@response.code).to eq(expected_code)
109
+ expect(@response.message).to eq(expected_message)
110
+ end
111
+ end
112
+
113
+ context "unauthorized response" do
114
+ let(:token) { "143250b7c5b996b2fb5e65ee4a6b870b9bd3297" }
115
+
116
+ it "returns the request response with access to the code, message, and body" do
117
+
118
+ VCR.use_cassette 'add_kit_unauthorized_error' do
119
+ allow(subject).to receive(:token).and_return(token)
120
+ @response = subject.response
121
+ end
122
+
123
+ expected_code = "401"
124
+ expected_message = "Unauthorized"
125
+ expected_body = "{\"errors\":[\"Not authorized\"]}"
126
+ expect(@response.body).to eq(expected_body)
127
+ expect(@response.code).to eq(expected_code)
128
+ expect(@response.message).to eq(expected_message)
129
+ end
130
+ end
131
+
132
+ context "maximum kits response" do
133
+ it "returns the request response with access to the code, message, and body" do
134
+
135
+ VCR.use_cassette 'add_kit_maximum_error' do
136
+ allow(subject).to receive(:token).and_return(token)
137
+ @response = subject.response
138
+ end
139
+
140
+ expected_code = "400"
141
+ expected_message = "Bad Request"
142
+ expected_body = "{\"errors\":[\"You have reached the maximum number of kits\"]}"
143
+ expect(@response.body).to eq(expected_body)
144
+ expect(@response.code).to eq(expected_code)
145
+ expect(@response.message).to eq(expected_message)
146
+ end
147
+ end
148
+ end
149
+ end
150
+ end
151
+ end
@@ -0,0 +1,199 @@
1
+ require 'spec_helper'
2
+
3
+ module Typekitable
4
+ describe ResponseFormatter do
5
+
6
+ let(:success_response) do
7
+ double(
8
+ :response,
9
+ :code => "200",
10
+ :message => "OK",
11
+ :body => "{\"kits\":[{\"id\":\"yuw0tqs\",\"link\":\"/api/v1/json/kits/yuw0tqs\"}]}"
12
+ )
13
+ end
14
+
15
+ let(:successful_response_with_long_body) do
16
+ double(
17
+ :response,
18
+ :code => "200",
19
+ :message => "OK",
20
+ :body => "{\"libraries\":[{\"id\":\"trial\",\"link\":\"/api/v1/json/libraries/trial\",\"name\":\"Trial Library\"},{\"id\":\"personal\",\"link\":\"/api/v1/json/libraries/personal\",\"name\":\"Personal Library\"},{\"id\":\"full\",\"link\":\"/api/v1/json/libraries/full\",\"name\":\"Full Library\"}]}"
21
+ )
22
+ end
23
+
24
+ let(:singular_resource_response) do
25
+ double(
26
+ :response,
27
+ :code => "200",
28
+ :message => "OK",
29
+ :body => "{\"kit\":{\"id\":\"fla3cfh\",\"name\":\"A new kit\",\"analytics\":false,\"domains\":[\"persazula.com\"],\"families\":[]}}"
30
+ )
31
+ end
32
+
33
+ let(:short_response) do
34
+ double(
35
+ :response,
36
+ :code => "200",
37
+ :message => "OK",
38
+ :body => "{\"published\":\"2015-04-26T23:35:33Z\"}"
39
+ )
40
+ end
41
+
42
+ let(:empty_response) do
43
+ double(
44
+ :response,
45
+ :code => "200",
46
+ :message => "OK",
47
+ :body => "{\"kits\":[{}]}"
48
+ )
49
+ end
50
+
51
+ let(:error_response) do
52
+ double(
53
+ :response,
54
+ :code => "401",
55
+ :message => "Unauthorized",
56
+ :body => "{\"errors\":[\"Not authorized\"]}"
57
+ )
58
+ end
59
+
60
+ context ".error" do
61
+ context "with successful response code" do
62
+ subject { described_class.new(success_response) }
63
+
64
+ it "returns false" do
65
+ expect(subject.error?).to be_falsey
66
+ end
67
+ end
68
+
69
+ context "with unsuccessful response code" do
70
+ subject { described_class.new(error_response) }
71
+
72
+ it "returns false" do
73
+ expect(subject.error?).to be_truthy
74
+ end
75
+ end
76
+ end
77
+
78
+ context ".parsed_body" do
79
+ context "success response" do
80
+ subject { described_class.new(success_response) }
81
+
82
+ it "formats the body to a usable hash structure" do
83
+ expect(subject.parsed_body).to eq({:kits => [{:id =>"yuw0tqs", :link =>"/api/v1/json/kits/yuw0tqs"}]})
84
+ end
85
+ end
86
+
87
+ context "error response" do
88
+ subject { described_class.new(error_response) }
89
+
90
+ it "formats the body to a usable hash structure" do
91
+ expect(subject.parsed_body).to eq({:errors => ["Not authorized"]})
92
+ end
93
+ end
94
+ end
95
+
96
+ context ".table_headers" do
97
+ subject { described_class.new(successful_response_with_long_body) }
98
+
99
+ it "formats the table headers for a collection" do
100
+ expected_headers = [:id, :link, :name]
101
+
102
+ expect(subject.table_headers).to eq(expected_headers)
103
+ end
104
+
105
+ it "formats the table headers for a singular resource" do
106
+ singular_resource_subject = described_class.new(singular_resource_response)
107
+ expected_headers = [:id, :name, :analytics, :domains, :families]
108
+
109
+ expect(singular_resource_subject.table_headers).to eq(expected_headers)
110
+ end
111
+
112
+ it "formats the table header for a short message" do
113
+ expected_header = [:published]
114
+
115
+ expect(described_class.new(short_response).table_headers).to eq(expected_header)
116
+ end
117
+
118
+ it "formats the table headers for an empty response" do
119
+ response = described_class.new(empty_response)
120
+ expected_headers = []
121
+
122
+ expect(response.table_headers).to eq(expected_headers)
123
+ end
124
+
125
+ it "formats the table header if an error response is detected" do
126
+ error_subject = described_class.new(error_response)
127
+
128
+ expect(error_subject.table_headers).to eq(["401"])
129
+ end
130
+ end
131
+
132
+ context ".table_body" do
133
+ subject { described_class.new(successful_response_with_long_body) }
134
+
135
+ it "formats the table body for a collection" do
136
+ expected_body = [
137
+ {
138
+ :id => "trial",
139
+ :link => "/api/v1/json/libraries/trial",
140
+ :name=> "Trial Library"
141
+ },
142
+ {
143
+ :id => "personal",
144
+ :link => "/api/v1/json/libraries/personal",
145
+ :name => "Personal Library"
146
+ },
147
+ {
148
+ :id => "full",
149
+ :link => "/api/v1/json/libraries/full",
150
+ :name => "Full Library"
151
+ }
152
+ ]
153
+ expect(subject.table_body).to eq(expected_body)
154
+ end
155
+
156
+ it "formats the table body for errors" do
157
+ error_subject = described_class.new(error_response)
158
+
159
+ expect(error_subject.table_body).to eq([{"401"=>"Not authorized"}])
160
+ end
161
+
162
+ it "formats the table body for a singular resource" do
163
+ singular_resource_subject = described_class.new(singular_resource_response)
164
+
165
+ expected_body = [
166
+ {
167
+ :id => "fla3cfh",
168
+ :name => "A new kit",
169
+ :analytics => false,
170
+ :domains => ["persazula.com"],
171
+ :families => []
172
+ }
173
+ ]
174
+
175
+ expect(singular_resource_subject.table_body).to eq(expected_body)
176
+ end
177
+
178
+ it "formats the table body for a short message" do
179
+ expected_body = [{:published => "2015-04-26T23:35:33Z"}]
180
+
181
+ expect(described_class.new(short_response).table_body).to eq(expected_body)
182
+ end
183
+
184
+ it "formats the table body when no data is received" do
185
+ response = described_class.new(empty_response)
186
+
187
+ expect(response.table_body).to eq([{}])
188
+ end
189
+ end
190
+
191
+ context ".data_heading" do
192
+ subject { described_class.new(successful_response_with_long_body) }
193
+
194
+ it "formats the data heading for display" do
195
+ expect(subject.data_heading).to eq("Libraries")
196
+ end
197
+ end
198
+ end
199
+ end
@@ -0,0 +1,48 @@
1
+ require 'spec_helper'
2
+
3
+ module Typekitable
4
+ describe Tokenizer do
5
+ subject { described_class }
6
+ let(:token_store) { double(:file) }
7
+ let(:example_token) { "4d6141e7c82cb30affebcc392abc2ce3ab0ea4c1" }
8
+
9
+ context "#store" do
10
+ it "stores a given API token" do
11
+ expect(File).to receive(:open).with(Tokenizer::TOKEN_STORE, 'w').and_yield(token_store)
12
+ expect(token_store).to receive(:write).with(example_token)
13
+
14
+ subject.store(example_token)
15
+ end
16
+ end
17
+
18
+ context "#has_token?" do
19
+ it "returns true when a token file exists" do
20
+ expect(File).to receive(:exist?).with(Tokenizer::TOKEN_STORE).and_return(true)
21
+
22
+ expect(subject.has_token?).to be_truthy
23
+ end
24
+
25
+ it "returns false when a token file does not exist" do
26
+ expect(File).to receive(:exist?).with(Tokenizer::TOKEN_STORE).and_return(false)
27
+
28
+ expect(subject.has_token?).to be_falsey
29
+ end
30
+ end
31
+
32
+ context "#get_token" do
33
+ it "returns the token when one exists" do
34
+ allow(subject).to receive(:has_token?).and_return(true)
35
+ expect(File).to receive(:open).with(Tokenizer::TOKEN_STORE, 'r').and_yield(token_store)
36
+ expect(token_store).to receive(:gets).and_return(example_token)
37
+
38
+ expect(subject.get_token).to eq(example_token)
39
+ end
40
+
41
+ it "returns nil when the token does not exist" do
42
+ allow(subject).to receive(:has_token?).and_return(false)
43
+
44
+ expect(subject.get_token).to be_nil
45
+ end
46
+ end
47
+ end
48
+ end
@@ -0,0 +1,23 @@
1
+ require 'typekitable'
2
+ require 'vcr'
3
+ require 'webmock/rspec'
4
+
5
+ VCR.configure do |c|
6
+ c.cassette_library_dir = './spec/fixtures/vcr_cassettes'
7
+ c.hook_into :webmock
8
+ end
9
+
10
+ RSpec.configure do |config|
11
+ def capture(stream)
12
+ begin
13
+ stream = stream.to_s
14
+ eval "$#{stream} = StringIO.new"
15
+ yield
16
+ result = eval("$#{stream}").string
17
+ ensure
18
+ eval("$#{stream} = #{stream.upcase}")
19
+ end
20
+
21
+ result
22
+ end
23
+ end
@@ -0,0 +1,24 @@
1
+ # coding: utf-8
2
+ lib = File.expand_path('../lib', __FILE__)
3
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
+ require 'typekitable/version'
5
+
6
+ Gem::Specification.new do |spec|
7
+ spec.name = "typekitable"
8
+ spec.version = Typekitable::VERSION
9
+ spec.authors = ["Persa Zula"]
10
+ spec.email = ["persa@persazula.com"]
11
+ spec.summary = %q{A CLI for interacting with your Typekit kits. No need to form your own requests!}
12
+ spec.homepage = "http://github.com/pzula/typekitable"
13
+ spec.license = "MIT"
14
+
15
+ spec.files = `git ls-files -z`.split("\x0")
16
+ spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
17
+ spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
18
+ spec.require_paths = ["lib"]
19
+
20
+ spec.add_dependency "thor", "0.19.1"
21
+ spec.add_dependency "formatador", "0.2.5"
22
+ spec.add_development_dependency "bundler", "~> 1.6"
23
+ spec.add_development_dependency "rake"
24
+ end