gradesfirst 0.2.1 → 0.3.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/.gitignore +1 -0
- data/Gemfile +1 -2
- data/Gemfile.lock +2 -6
- data/gradesfirst.gemspec +2 -2
- data/lib/gradesfirst.rb +1 -0
- data/lib/gradesfirst/cli.rb +7 -29
- data/lib/gradesfirst/cli_helper.rb +33 -0
- data/lib/gradesfirst/command.rb +7 -0
- data/lib/gradesfirst/commit_message_command.rb +1 -1
- data/lib/gradesfirst/task_add_command.rb +51 -0
- data/lib/gradesfirst/task_cli.rb +48 -0
- data/lib/gradesfirst/task_command.rb +38 -30
- data/lib/gradesfirst/task_delete_command.rb +64 -0
- data/lib/gradesfirst/task_list_command.rb +40 -0
- data/lib/gradesfirst/task_move_command.rb +64 -0
- data/lib/gradesfirst/task_toggle_command.rb +65 -0
- data/lib/http_magic.rb +2 -258
- data/lib/http_magic/api.rb +233 -0
- data/lib/http_magic/request.rb +93 -0
- data/lib/http_magic/uri.rb +74 -0
- data/lib/pivotal_tracker.rb +1 -1
- data/test/branch_command_test.rb +8 -21
- data/test/cli_test.rb +51 -34
- data/test/command_test.rb +5 -7
- data/test/commit_message_command_test.rb +37 -45
- data/test/fixtures/task.json +10 -0
- data/test/fixtures/task_added.txt +6 -0
- data/test/fixtures/task_deleted.txt +6 -0
- data/test/fixtures/task_moved.txt +6 -0
- data/test/fixtures/task_toggled.txt +6 -0
- data/test/fixtures/tasks.txt +2 -2
- data/test/http_magic/{get_test.rb → api/get_test.rb} +1 -1
- data/test/http_magic/api/post_test.rb +34 -0
- data/test/http_magic/request_test.rb +63 -0
- data/test/http_magic/uri_test.rb +28 -55
- data/test/support/pivotal_test_helper.rb +110 -0
- data/test/support/request_expectation.rb +33 -0
- data/test/task_add_command_test.rb +54 -0
- data/test/task_delete_command_test.rb +57 -0
- data/test/task_list_command_test.rb +18 -0
- data/test/task_move_command_test.rb +66 -0
- data/test/task_toggle_command_test.rb +58 -0
- data/test/test_helper.rb +35 -19
- metadata +29 -7
- data/test/pivotal_tracker_test.rb +0 -46
- data/test/task_command_test.rb +0 -52
data/test/fixtures/tasks.txt
CHANGED
@@ -0,0 +1,34 @@
|
|
1
|
+
require 'test_helper'
|
2
|
+
require 'http_magic'
|
3
|
+
|
4
|
+
class HttpMagicTest < HttpMagic::Api
|
5
|
+
end
|
6
|
+
|
7
|
+
describe 'HttpMagic#post' do
|
8
|
+
before do
|
9
|
+
@url = HttpMagicTest.url 'www.example.com'
|
10
|
+
HttpMagicTest.namespace nil
|
11
|
+
HttpMagicTest.headers nil
|
12
|
+
end
|
13
|
+
|
14
|
+
it 'should send POST request' do
|
15
|
+
stub_post = stub_request(:post, "https://#{@url}")
|
16
|
+
|
17
|
+
HttpMagicTest.post
|
18
|
+
assert_requested stub_post
|
19
|
+
end
|
20
|
+
|
21
|
+
it 'should send data with POST request' do
|
22
|
+
expected_data = {
|
23
|
+
apple: 'sauce',
|
24
|
+
banana: 'bread'
|
25
|
+
}
|
26
|
+
stub_post = stub_request(:post, "https://#{@url}/foo").with(
|
27
|
+
body: expected_data
|
28
|
+
)
|
29
|
+
|
30
|
+
HttpMagicTest.foo.post(expected_data)
|
31
|
+
|
32
|
+
assert_requested stub_post
|
33
|
+
end
|
34
|
+
end
|
@@ -0,0 +1,63 @@
|
|
1
|
+
require 'test_helper'
|
2
|
+
require 'http_magic/uri'
|
3
|
+
require 'http_magic/request'
|
4
|
+
|
5
|
+
describe 'HttpMagic::Request' do
|
6
|
+
before do
|
7
|
+
@domain = 'example.com'
|
8
|
+
@uri = HttpMagic::Uri.new(@domain)
|
9
|
+
end
|
10
|
+
|
11
|
+
it 'should make a request' do
|
12
|
+
stub_request = stub_request(
|
13
|
+
:get,
|
14
|
+
"https://#{@domain}/api/v2/path/to/something"
|
15
|
+
)
|
16
|
+
|
17
|
+
@uri.namespace = 'api/v2'
|
18
|
+
@uri.parts = ['path', 'to', 'something']
|
19
|
+
request = HttpMagic::Request.new(@uri)
|
20
|
+
request.get
|
21
|
+
|
22
|
+
assert_requested stub_request
|
23
|
+
end
|
24
|
+
|
25
|
+
it 'should return content on request' do
|
26
|
+
content = 'This is SPARTA!'
|
27
|
+
stub_request(:get, "https://#{@domain}").
|
28
|
+
to_return(body: content)
|
29
|
+
|
30
|
+
request = HttpMagic::Request.new(@uri)
|
31
|
+
|
32
|
+
assert_equal content, request.get
|
33
|
+
end
|
34
|
+
|
35
|
+
it 'should be able to post data as hash' do
|
36
|
+
expected_data = {
|
37
|
+
apple: 'crispy',
|
38
|
+
banana: 'soft'
|
39
|
+
}
|
40
|
+
stub_request = stub_request(:post, "https://#{@domain}").with(
|
41
|
+
body: expected_data.to_json,
|
42
|
+
headers: { 'content-type' => 'application/json' }
|
43
|
+
)
|
44
|
+
|
45
|
+
request = HttpMagic::Request.new(@uri, data: expected_data)
|
46
|
+
request.post
|
47
|
+
|
48
|
+
assert_requested stub_request
|
49
|
+
end
|
50
|
+
|
51
|
+
it 'should set correct headers' do
|
52
|
+
stub_request = stub_request(:get, "https://#{@domain}").
|
53
|
+
with(headers: { 'X-AuthToken' => 'test_token' })
|
54
|
+
|
55
|
+
request = HttpMagic::Request.new(
|
56
|
+
@uri,
|
57
|
+
headers: { 'X-AuthToken' => 'test_token' }
|
58
|
+
)
|
59
|
+
request.get
|
60
|
+
|
61
|
+
assert_requested stub_request
|
62
|
+
end
|
63
|
+
end
|
data/test/http_magic/uri_test.rb
CHANGED
@@ -1,76 +1,49 @@
|
|
1
1
|
require 'test_helper'
|
2
|
-
require 'http_magic'
|
2
|
+
require 'http_magic/uri'
|
3
3
|
|
4
|
-
|
5
|
-
end
|
6
|
-
|
7
|
-
describe 'HttpMagic#uri' do
|
4
|
+
describe 'HttpMagic::Uri' do
|
8
5
|
before do
|
9
|
-
@
|
10
|
-
|
11
|
-
end
|
12
|
-
|
13
|
-
it 'should make a good root uri' do
|
14
|
-
assert_equal(
|
15
|
-
"#{@url}/",
|
16
|
-
HttpMagicTest.uri
|
17
|
-
)
|
6
|
+
@domain = 'example.com'
|
7
|
+
@uri = uri = HttpMagic::Uri.new(@domain)
|
18
8
|
end
|
19
9
|
|
20
|
-
it '
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
)
|
10
|
+
it 'must have a domain param' do
|
11
|
+
assert_raises ArgumentError do
|
12
|
+
HttpMagic::Uri.new
|
13
|
+
end
|
25
14
|
end
|
26
15
|
|
27
|
-
it 'should
|
28
|
-
assert_equal
|
29
|
-
"#{@url}/foos",
|
30
|
-
HttpMagicTest.foos.uri
|
31
|
-
)
|
16
|
+
it 'should return the domain' do
|
17
|
+
assert_equal @domain, @uri.domain
|
32
18
|
end
|
33
19
|
|
34
|
-
it '
|
35
|
-
assert_equal
|
36
|
-
"#{@url}/foos/99",
|
37
|
-
HttpMagicTest.foos[99].uri
|
38
|
-
)
|
20
|
+
it 'can build a simple uri' do
|
21
|
+
assert_equal "https://#{@domain}/", @uri.build
|
39
22
|
end
|
40
23
|
|
41
|
-
it 'should
|
42
|
-
assert_equal
|
43
|
-
"#{@url}/foos/99/bars",
|
44
|
-
HttpMagicTest.foos[99].bars.uri
|
45
|
-
)
|
24
|
+
it 'should have url' do
|
25
|
+
assert_equal "https://#{@domain}", @uri.url
|
46
26
|
end
|
47
27
|
|
48
|
-
it 'should
|
49
|
-
|
50
|
-
|
51
|
-
HttpMagicTest[:get].uri
|
52
|
-
)
|
28
|
+
it 'should create urn with parts' do
|
29
|
+
@uri.parts = ['path', 'to', 'something']
|
30
|
+
assert_equal '/path/to/something', @uri.urn
|
53
31
|
end
|
54
32
|
|
55
|
-
it 'should
|
56
|
-
|
57
|
-
|
58
|
-
HttpMagicTest.foo[:get].bar.uri
|
59
|
-
)
|
33
|
+
it 'should create urn with namespace' do
|
34
|
+
@uri.namespace = 'api/v2'
|
35
|
+
assert_equal '/api/v2', @uri.urn
|
60
36
|
end
|
61
37
|
|
62
|
-
it 'should
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
)
|
38
|
+
it 'should create urn with namespace and parts combined' do
|
39
|
+
@uri.parts = ['path', 'to', 'something']
|
40
|
+
@uri.namespace = 'api/v2'
|
41
|
+
assert_equal '/api/v2/path/to/something', @uri.urn
|
67
42
|
end
|
68
43
|
|
69
|
-
it 'should
|
70
|
-
|
71
|
-
|
72
|
-
|
73
|
-
HttpMagicTest.foo.bar[:get].uri
|
74
|
-
)
|
44
|
+
it 'should create the full uri with urn included' do
|
45
|
+
@uri.parts = ['path', 'to', 'something']
|
46
|
+
@uri.namespace = 'api/v2'
|
47
|
+
assert_equal "https://#{@domain}/api/v2/path/to/something", @uri.build
|
75
48
|
end
|
76
49
|
end
|
@@ -0,0 +1,110 @@
|
|
1
|
+
module GradesFirst
|
2
|
+
module PivotalTestHelper
|
3
|
+
|
4
|
+
def bar_story_id
|
5
|
+
'29384793'
|
6
|
+
end
|
7
|
+
|
8
|
+
def foo_story_id
|
9
|
+
'57348714'
|
10
|
+
end
|
11
|
+
|
12
|
+
def missing_story_id
|
13
|
+
'29384799'
|
14
|
+
end
|
15
|
+
|
16
|
+
def pivotal_tracker_setup
|
17
|
+
PivotalTracker.api_token = 'test_token'
|
18
|
+
end
|
19
|
+
|
20
|
+
def stub_bar_story_request
|
21
|
+
stub_pivotal_request(
|
22
|
+
:get,
|
23
|
+
'stories/' + bar_story_id,
|
24
|
+
response: { body: fixture_file('story_bar.json') }
|
25
|
+
)
|
26
|
+
end
|
27
|
+
|
28
|
+
def stub_bar_story_tasks_request
|
29
|
+
stub_pivotal_request(
|
30
|
+
:get,
|
31
|
+
urn_for_bar_story_tasks,
|
32
|
+
response: { body: fixture_file('tasks.json') }
|
33
|
+
)
|
34
|
+
end
|
35
|
+
|
36
|
+
def stub_foo_story_request
|
37
|
+
stub_pivotal_request(
|
38
|
+
:get,
|
39
|
+
'stories/' + foo_story_id,
|
40
|
+
response: { body: fixture_file('story_foo.json') }
|
41
|
+
)
|
42
|
+
end
|
43
|
+
|
44
|
+
def stub_missing_story_request
|
45
|
+
stub_pivotal_request(
|
46
|
+
:get,
|
47
|
+
'stories/' + missing_story_id,
|
48
|
+
response: { status: 404 }
|
49
|
+
)
|
50
|
+
end
|
51
|
+
|
52
|
+
# Simplify and DRY up stubbing out of PivotalTracker requests.
|
53
|
+
def stub_pivotal_request(method, urn, options = {})
|
54
|
+
default_request = {
|
55
|
+
headers: { 'X-TrackerToken' => 'test_token' }
|
56
|
+
}
|
57
|
+
if method == :post
|
58
|
+
default_request[:headers]['Content-Type'] = 'application/json'
|
59
|
+
end
|
60
|
+
default_response = {
|
61
|
+
headers: { 'Content-Type' => 'application/json' },
|
62
|
+
body: '',
|
63
|
+
status: 200
|
64
|
+
}
|
65
|
+
|
66
|
+
uri = "https://www.pivotaltracker.com:443/services/v5/#{urn}"
|
67
|
+
stub_request(method, uri).
|
68
|
+
with(default_request.merge(options[:request] || {})).
|
69
|
+
to_return(default_response.merge(options[:response] || {}))
|
70
|
+
|
71
|
+
RequestExpectation.new(method, uri)
|
72
|
+
end
|
73
|
+
|
74
|
+
def urn_for_bar_story_tasks
|
75
|
+
"projects/10687/stories/#{bar_story_id}/tasks"
|
76
|
+
end
|
77
|
+
|
78
|
+
def urn_for_bar_story_task(task_id)
|
79
|
+
urn_for_bar_story_tasks + "/#{task_id}"
|
80
|
+
end
|
81
|
+
|
82
|
+
module ClassMethods
|
83
|
+
|
84
|
+
def specify_response_for_invalid_story(*args)
|
85
|
+
specify '#response responds with error message with an invalid story' do
|
86
|
+
expect_requests stub_missing_story_request do
|
87
|
+
@command.stub :current_branch, missing_story_id do
|
88
|
+
@command.execute(*args)
|
89
|
+
end
|
90
|
+
end
|
91
|
+
assert_equal @command.send(:story_error_message), @command.response
|
92
|
+
end
|
93
|
+
end
|
94
|
+
|
95
|
+
def specify_response_for_invalid_task_position(method, *args)
|
96
|
+
specify '#response when position does not exist' do
|
97
|
+
stub_bar_story_request
|
98
|
+
stub_bar_story_tasks_request
|
99
|
+
@command.stub :current_branch, bar_story_id do
|
100
|
+
@command.execute(*args)
|
101
|
+
end
|
102
|
+
assert_equal @command.send(:position_invalid_message), @command.response
|
103
|
+
assert_not_requested method, /.*/
|
104
|
+
end
|
105
|
+
end
|
106
|
+
|
107
|
+
end
|
108
|
+
|
109
|
+
end
|
110
|
+
end
|
@@ -0,0 +1,33 @@
|
|
1
|
+
# This class encapsulates creating http request expectations with the webmock
|
2
|
+
# assert_requested assertion.
|
3
|
+
#
|
4
|
+
# Example:
|
5
|
+
# expectation = RequestExpectation(:get, 'http://example.com').times(2)
|
6
|
+
# assert_requested(*expectation.to_args)
|
7
|
+
class RequestExpectation
|
8
|
+
# Store the HTTP request method and uri that are expected and specifies the
|
9
|
+
# default number of times that the request is expected to made.
|
10
|
+
def initialize(method, uri)
|
11
|
+
@method = method
|
12
|
+
@uri = uri
|
13
|
+
@times = 1
|
14
|
+
end
|
15
|
+
|
16
|
+
# Specifies the number of times that a request is expected to be made.
|
17
|
+
#
|
18
|
+
# Example:
|
19
|
+
# RequestExpectation.new(:get, 'http://example.com').times(2).to_args
|
20
|
+
#
|
21
|
+
# Retuns an instance of itself to allow for method chaining.
|
22
|
+
def times(value)
|
23
|
+
@times = value
|
24
|
+
self
|
25
|
+
end
|
26
|
+
|
27
|
+
# Creates a set of method arguments for the Webmock assert_requested method.
|
28
|
+
#
|
29
|
+
# Returns an array of Webmock assert_request method arguments.
|
30
|
+
def to_args
|
31
|
+
[@method, @uri, { times: @times }]
|
32
|
+
end
|
33
|
+
end
|
@@ -0,0 +1,54 @@
|
|
1
|
+
require 'test_helper'
|
2
|
+
require 'gradesfirst/task_add_command'
|
3
|
+
|
4
|
+
describe GradesFirst::TaskAddCommand do
|
5
|
+
before do
|
6
|
+
@task_description = 'New task.'
|
7
|
+
@command = GradesFirst::TaskAddCommand.new
|
8
|
+
end
|
9
|
+
|
10
|
+
def stub_bar_story_task_add_request(response)
|
11
|
+
stub_pivotal_request(
|
12
|
+
:post,
|
13
|
+
urn_for_bar_story_tasks,
|
14
|
+
request: { body: "{\"description\":\"#{@task_description}\"}" },
|
15
|
+
response: response
|
16
|
+
)
|
17
|
+
end
|
18
|
+
|
19
|
+
def stub_failing_bar_story_task_add_request
|
20
|
+
stub_bar_story_task_add_request status: 500
|
21
|
+
end
|
22
|
+
|
23
|
+
def stub_working_bar_story_task_add_request
|
24
|
+
stub_bar_story_task_add_request body: fixture_file('task.json')
|
25
|
+
end
|
26
|
+
|
27
|
+
specify '#response responds with confirmation and task list' do
|
28
|
+
stubbed_requests = [
|
29
|
+
stub_bar_story_request,
|
30
|
+
stub_bar_story_tasks_request,
|
31
|
+
stub_working_bar_story_task_add_request
|
32
|
+
]
|
33
|
+
|
34
|
+
response = nil
|
35
|
+
expect_requests stubbed_requests do
|
36
|
+
@command.stub :current_branch, bar_story_id do
|
37
|
+
@command.execute(@task_description)
|
38
|
+
end
|
39
|
+
response = @command.response
|
40
|
+
end
|
41
|
+
assert_equal fixture_file('task_added.txt'), response
|
42
|
+
end
|
43
|
+
|
44
|
+
specify '#response when adding the task fails' do
|
45
|
+
stub_bar_story_request
|
46
|
+
stub_failing_bar_story_task_add_request
|
47
|
+
@command.stub :current_branch, bar_story_id do
|
48
|
+
@command.execute(@task_description)
|
49
|
+
end
|
50
|
+
assert_equal @command.send(:task_error_message), @command.response
|
51
|
+
end
|
52
|
+
|
53
|
+
specify_response_for_invalid_story @task_description
|
54
|
+
end
|