gradesfirst 0.2.1 → 0.3.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (46) hide show
  1. data/.gitignore +1 -0
  2. data/Gemfile +1 -2
  3. data/Gemfile.lock +2 -6
  4. data/gradesfirst.gemspec +2 -2
  5. data/lib/gradesfirst.rb +1 -0
  6. data/lib/gradesfirst/cli.rb +7 -29
  7. data/lib/gradesfirst/cli_helper.rb +33 -0
  8. data/lib/gradesfirst/command.rb +7 -0
  9. data/lib/gradesfirst/commit_message_command.rb +1 -1
  10. data/lib/gradesfirst/task_add_command.rb +51 -0
  11. data/lib/gradesfirst/task_cli.rb +48 -0
  12. data/lib/gradesfirst/task_command.rb +38 -30
  13. data/lib/gradesfirst/task_delete_command.rb +64 -0
  14. data/lib/gradesfirst/task_list_command.rb +40 -0
  15. data/lib/gradesfirst/task_move_command.rb +64 -0
  16. data/lib/gradesfirst/task_toggle_command.rb +65 -0
  17. data/lib/http_magic.rb +2 -258
  18. data/lib/http_magic/api.rb +233 -0
  19. data/lib/http_magic/request.rb +93 -0
  20. data/lib/http_magic/uri.rb +74 -0
  21. data/lib/pivotal_tracker.rb +1 -1
  22. data/test/branch_command_test.rb +8 -21
  23. data/test/cli_test.rb +51 -34
  24. data/test/command_test.rb +5 -7
  25. data/test/commit_message_command_test.rb +37 -45
  26. data/test/fixtures/task.json +10 -0
  27. data/test/fixtures/task_added.txt +6 -0
  28. data/test/fixtures/task_deleted.txt +6 -0
  29. data/test/fixtures/task_moved.txt +6 -0
  30. data/test/fixtures/task_toggled.txt +6 -0
  31. data/test/fixtures/tasks.txt +2 -2
  32. data/test/http_magic/{get_test.rb → api/get_test.rb} +1 -1
  33. data/test/http_magic/api/post_test.rb +34 -0
  34. data/test/http_magic/request_test.rb +63 -0
  35. data/test/http_magic/uri_test.rb +28 -55
  36. data/test/support/pivotal_test_helper.rb +110 -0
  37. data/test/support/request_expectation.rb +33 -0
  38. data/test/task_add_command_test.rb +54 -0
  39. data/test/task_delete_command_test.rb +57 -0
  40. data/test/task_list_command_test.rb +18 -0
  41. data/test/task_move_command_test.rb +66 -0
  42. data/test/task_toggle_command_test.rb +58 -0
  43. data/test/test_helper.rb +35 -19
  44. metadata +29 -7
  45. data/test/pivotal_tracker_test.rb +0 -46
  46. data/test/task_command_test.rb +0 -52
@@ -0,0 +1,6 @@
1
+ Task was successfully added.
2
+
3
+ Bring me the passengers (http://www.pivotaltracker.com/story/show/29384793)
4
+
5
+ 1. [X] Port 0
6
+ 2. [ ] Port 90
@@ -0,0 +1,6 @@
1
+ Task was successfully deleted.
2
+
3
+ Bring me the passengers (http://www.pivotaltracker.com/story/show/29384793)
4
+
5
+ 1. [X] Port 0
6
+ 2. [ ] Port 90
@@ -0,0 +1,6 @@
1
+ Task was successfully moved.
2
+
3
+ Bring me the passengers (http://www.pivotaltracker.com/story/show/29384793)
4
+
5
+ 1. [X] Port 0
6
+ 2. [ ] Port 90
@@ -0,0 +1,6 @@
1
+ Task completion status was successfully toggled.
2
+
3
+ Bring me the passengers (http://www.pivotaltracker.com/story/show/29384793)
4
+
5
+ 1. [X] Port 0
6
+ 2. [ ] Port 90
@@ -1,4 +1,4 @@
1
1
  Bring me the passengers (http://www.pivotaltracker.com/story/show/29384793)
2
2
 
3
- [X] Port 0
4
- [ ] Port 90
3
+ 1. [X] Port 0
4
+ 2. [ ] Port 90
@@ -1,7 +1,7 @@
1
1
  require 'test_helper'
2
2
  require 'http_magic'
3
3
 
4
- class HttpMagicTest < HttpMagic
4
+ class HttpMagicTest < HttpMagic::Api
5
5
  end
6
6
 
7
7
  describe 'HttpMagic#get' do
@@ -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
@@ -1,76 +1,49 @@
1
1
  require 'test_helper'
2
- require 'http_magic'
2
+ require 'http_magic/uri'
3
3
 
4
- class HttpMagicTest < HttpMagic
5
- end
6
-
7
- describe 'HttpMagic#uri' do
4
+ describe 'HttpMagic::Uri' do
8
5
  before do
9
- @url = HttpMagicTest.url 'www.example.com'
10
- HttpMagicTest.namespace nil
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 'should make a uri that begins with new' do
21
- assert_equal(
22
- "#{@url}/new",
23
- HttpMagicTest.new.uri
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 make a good single part uri' do
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 'should make a good uri with an index' do
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 make a good nested uri' do
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 make a uri including a keyword at the beginning' do
49
- assert_equal(
50
- "#{@url}/get",
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 make a uri including a keyword in the middle' do
56
- assert_equal(
57
- "#{@url}/foo/get/bar",
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 make a uri including a keyword at the end' do
63
- assert_equal(
64
- "#{@url}/foo/bar/get",
65
- HttpMagicTest.foo.bar[:get].uri
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 make a namespaced uri' do
70
- HttpMagicTest.namespace 'api/v5'
71
- assert_equal(
72
- "#{@url}/api/v5/foo/bar/get",
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