rsimpy 0.1.2

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.
Files changed (54) hide show
  1. data/.document +5 -0
  2. data/.gitignore +7 -0
  3. data/LICENSE +20 -0
  4. data/README.rdoc +21 -0
  5. data/Rakefile +96 -0
  6. data/VERSION.yml +4 -0
  7. data/bin/simp +68 -0
  8. data/features/links/adding_a_link.feature +47 -0
  9. data/features/links/querying_links.feature +46 -0
  10. data/features/links/steps/link_steps.rb +39 -0
  11. data/features/notes/query_note.feature +27 -0
  12. data/features/notes/remove_note.feature +11 -0
  13. data/features/notes/save_note.feature +36 -0
  14. data/features/notes/steps/note_steps.rb +46 -0
  15. data/features/support/env.rb +22 -0
  16. data/features/tags/merge_tags.feature +13 -0
  17. data/features/tags/querying_tags.feature +19 -0
  18. data/features/tags/remove_tag.feature +11 -0
  19. data/features/tags/rename_tag.feature +12 -0
  20. data/features/tags/split_tag.feature +13 -0
  21. data/features/tags/steps/tag_steps.rb +49 -0
  22. data/lib/base_service.rb +28 -0
  23. data/lib/client.rb +45 -0
  24. data/lib/configuration.rb +21 -0
  25. data/lib/errors/connection_error.rb +6 -0
  26. data/lib/errors/required_field_missing_error.rb +9 -0
  27. data/lib/errors/user_not_provided_error.rb +4 -0
  28. data/lib/links.rb +62 -0
  29. data/lib/parameters.rb +120 -0
  30. data/lib/posting_service.rb +27 -0
  31. data/lib/profile_storage_service.rb +47 -0
  32. data/lib/querying_service.rb +31 -0
  33. data/lib/rsimpy.rb +62 -0
  34. data/lib/user.rb +31 -0
  35. data/rsimpy.gemspec +128 -0
  36. data/test/client_test.rb +40 -0
  37. data/test/configuration_test.rb +27 -0
  38. data/test/deleting_service_test.rb +51 -0
  39. data/test/fixtures/test +5 -0
  40. data/test/fixtures/user_pass +5 -0
  41. data/test/links_test.rb +47 -0
  42. data/test/parameters_test.rb +61 -0
  43. data/test/posting_service_test.rb +45 -0
  44. data/test/profile_storage_service_test.rb +34 -0
  45. data/test/querying_service_test.rb +31 -0
  46. data/test/r_simpy_test.rb +74 -0
  47. data/test/required_field_missing_error_test.rb +11 -0
  48. data/test/responsive.rb +154 -0
  49. data/test/storage_builder.rb +16 -0
  50. data/test/storage_service_mock.rb +16 -0
  51. data/test/test_helper.rb +18 -0
  52. data/test/user_not_provided_error_test.rb +7 -0
  53. data/test/user_test.rb +34 -0
  54. metadata +182 -0
@@ -0,0 +1,22 @@
1
+ $LOAD_PATH.unshift(File.dirname(__FILE__))
2
+ $LOAD_PATH.unshift(File.join(File.dirname(__FILE__), '..', '..', 'lib'))
3
+
4
+ $LOAD_PATH.unshift(File.join(File.dirname(__FILE__), '..', '..', 'test'))
5
+ require 'fakeweb'
6
+ require 'responsive'
7
+
8
+ require 'test/unit/assertions'
9
+ World(Test::Unit::Assertions)
10
+
11
+ require 'rsimpy'
12
+
13
+ def convert_symbols_and_dates key, value
14
+ if /[Dd]ate/ =~ key
15
+ return Date.strptime(value, '%m/%d/%Y')
16
+ else
17
+ return value unless value[0] == ":"[0]
18
+
19
+ len = value.length
20
+ value[1..len].to_sym
21
+ end
22
+ end
@@ -0,0 +1,13 @@
1
+ Feature: Merge tags in my simpy account
2
+ In order to better organize my simpy account
3
+ As a simpy user
4
+ I want to merge two tags in my simpy account via rsimpy
5
+
6
+ Scenario: Basic tag splitting
7
+ Given a user of "USERNAME" with a password of "PASSWORD"
8
+ When I merge a user's tags
9
+ When the "toTag" is "api"
10
+ And the "fromTag1" is "programming"
11
+ And the "fromTag2" is "interface"
12
+ Then I expect to merge the tags with the url "http://USERNAME:PASSWORD@www.simpy.com:80/simpy/api/rest/MergeTags.do?fromTag1=programming&fromTag2=interface&src=rsimpy&toTag=api"
13
+ Then the response is successful
@@ -0,0 +1,19 @@
1
+ Feature: Query tags from a simpy account
2
+ In order to know more about my tags
3
+ As a simpy user
4
+ I want to query my simpy account via rsimpy
5
+
6
+ Scenario: Basic tag query
7
+ Given a user of "USERNAME" with a password of "PASSWORD"
8
+ When I query the user's tags
9
+ Then I expect to query tags from the url "http://USERNAME:PASSWORD@www.simpy.com:80/simpy/api/rest/GetTags.do?src=rsimpy"
10
+ Then the tags are returned
11
+ And the response is successful
12
+
13
+ Scenario: Tag query with limit
14
+ Given a user of "USERNAME" with a password of "PASSWORD"
15
+ When I query the user's tags
16
+ And the "limit" is "50"
17
+ Then I expect to query tags from the url "http://USERNAME:PASSWORD@www.simpy.com:80/simpy/api/rest/GetTags.do?limit=50&src=rsimpy"
18
+ Then the tags are returned
19
+ And the response is successful
@@ -0,0 +1,11 @@
1
+ Feature: Remove tag from my simpy account
2
+ In order to better organize my simpy account
3
+ As a simpy user
4
+ I want to remove a tag from my simpy account via rsimpy
5
+
6
+ Scenario: Removing a tag
7
+ Given a user of "USERNAME" with a password of "PASSWORD"
8
+ When I remove a user's tags
9
+ And the "tag" is "mutable"
10
+ Then I expect to remove the tag with the url "http://USERNAME:PASSWORD@www.simpy.com/simpy/api/rest/RemoveTag.do?tag=mutable&src=rsimpy"
11
+ Then the response is successful
@@ -0,0 +1,12 @@
1
+ Feature: Rename a tag in my simpy account
2
+ In order to better organize my simpy account
3
+ As a simpy user
4
+ I want to rename a tag in my simpy account via rsimpy
5
+
6
+ Scenario: Renaming a tag
7
+ Given a user of "USERNAME" with a password of "PASSWORD"
8
+ When I rename a user's tags
9
+ When the "fromTag" is "cheese"
10
+ And the "toTag" is "cheez"
11
+ Then I expect to rename the tag with the url "http://USERNAME:PASSWORD@www.simpy.com:80/simpy/api/rest/RenameTag.do?fromTag=cheese&src=rsimpy&toTag=cheez"
12
+ Then the response is successful
@@ -0,0 +1,13 @@
1
+ Feature: Split tags in my simpy account
2
+ In order to better organize my simpy account
3
+ As a simpy user
4
+ I want to split a tag in my simpy account via rsimpy
5
+
6
+ Scenario: Basic tag splitting
7
+ Given a user of "USERNAME" with a password of "PASSWORD"
8
+ When I split a user's tags
9
+ When the "tag" is "api"
10
+ And the "toTag1" is "programming"
11
+ And the "toTag2" is "interface"
12
+ Then I expect to split the tag with the url "http://USERNAME:PASSWORD@www.simpy.com/simpy/api/rest/SplitTag.do?tag=api&toTag1=programming&toTag2=interface&src=rsimpy"
13
+ Then the response is successful
@@ -0,0 +1,49 @@
1
+ include Responsive
2
+
3
+ When /^I ([^\"]*) a user's tags$/ do |verb|
4
+
5
+ end
6
+
7
+ Then /^I expect to split the tag with the url "([^\"]*)"$/ do |url|
8
+ FakeWeb.register_uri(:post, url, :string => tag_splitting_response)
9
+
10
+ @service = RSimpy::PostingService.new(RSimpy::SPLIT_TAG, @client)
11
+ @response = @service.execute @p
12
+ end
13
+
14
+ Then /^I expect to merge the tags with the url "([^\"]*)"$/ do |url|
15
+ FakeWeb.register_uri(:post, url, :string => tag_merging_response)
16
+
17
+ @service = RSimpy::PostingService.new(RSimpy::MERGE_TAGS, @client)
18
+ @response = @service.execute @p
19
+ end
20
+
21
+ Then /^I expect to rename the tag with the url "([^\"]*)"$/ do |url|
22
+ FakeWeb.register_uri(:post, url, :string => tag_renaming_response)
23
+
24
+ @service = RSimpy::PostingService.new(RSimpy::RENAME_TAG, @client)
25
+ @response = @service.execute @p
26
+ end
27
+
28
+ Then /^I expect to remove the tag with the url "([^\"]*)"$/ do |url|
29
+ FakeWeb.register_uri(:post, url, :string => tag_removing_response)
30
+
31
+ @service = RSimpy::PostingService.new(RSimpy::REMOVE_TAG, @client)
32
+ @response = @service.execute @p
33
+ end
34
+
35
+ When /^I query the user's tags$/ do
36
+
37
+ end
38
+
39
+ Then /^the tags are returned$/ do
40
+ assert @response.has_key? "tags"
41
+ end
42
+
43
+ Then /^I expect to query tags from the url "([^\"]*)"$/ do |url|
44
+ FakeWeb.register_uri(:get, url, :string => tag_querying_response)
45
+
46
+ @service = RSimpy::QueryingService.new(RSimpy::GET_TAGS, @client)
47
+ @response = @service.execute @p
48
+ end
49
+
@@ -0,0 +1,28 @@
1
+ module RSimpy
2
+ class BaseService
3
+ attr_reader :success, :status_message, :status_code
4
+
5
+ def reset
6
+ @success = false
7
+ @status_message = nil
8
+ @status_code = nil
9
+ end
10
+
11
+ def set_status response
12
+ @success = ((response.code == 200) && response['status']['code'] == "0")
13
+ if response.code == 200
14
+ @status_code = response['status']['code']
15
+ @status_message = response['status']['message']
16
+ end
17
+ end
18
+
19
+ def execute_using method, params
20
+ reset
21
+
22
+ response = @client.execute method, build_link(params)
23
+ set_status response
24
+
25
+ response
26
+ end
27
+ end
28
+ end
@@ -0,0 +1,45 @@
1
+ require 'errors/connection_error'
2
+
3
+ require 'rubygems'
4
+ gem 'httparty', '>= 0.4.2'
5
+ require 'httparty'
6
+
7
+
8
+ module RSimpy
9
+ class Client
10
+ include HTTParty
11
+ base_uri 'www.simpy.com/simpy/api/rest'
12
+ format :xml
13
+
14
+ def initialize(user)
15
+ raise RSimpy::UserNotProvidedError unless user && user.valid?
16
+ login, pass = user.credentials
17
+ self.class.basic_auth login, pass
18
+ end
19
+
20
+ def execute method, uri
21
+ case method
22
+ when :get
23
+ get uri
24
+ when :post
25
+ post uri
26
+ end
27
+ end
28
+
29
+ def get uri
30
+ begin
31
+ self.class.get uri
32
+ rescue SocketError => error
33
+ raise ConnectionError.new "Error connecting to Simpy: #{error.message}"
34
+ end
35
+ end
36
+
37
+ def post uri
38
+ begin
39
+ self.class.post uri
40
+ rescue SocketError => error
41
+ raise ConnectionError.new "Error connecting to Simpy: #{error.message}"
42
+ end
43
+ end
44
+ end
45
+ end
@@ -0,0 +1,21 @@
1
+ module RSimpy
2
+ class Configuration
3
+ attr_writer :user
4
+
5
+ def initialize storage_service
6
+ @storage_service = storage_service
7
+ end
8
+
9
+ def stored?
10
+ @storage_service.stored?
11
+ end
12
+
13
+ def save
14
+ @storage_service.save @user
15
+ end
16
+
17
+ def get
18
+ @storage_service.get
19
+ end
20
+ end
21
+ end
@@ -0,0 +1,6 @@
1
+
2
+ module RSimpy
3
+ class ConnectionError < RuntimeError
4
+
5
+ end
6
+ end
@@ -0,0 +1,9 @@
1
+ module RSimpy
2
+ class RequiredFieldMissingError < RuntimeError
3
+ attr_reader :field
4
+
5
+ def initialize field
6
+ @field = field
7
+ end
8
+ end
9
+ end
@@ -0,0 +1,4 @@
1
+ module RSimpy
2
+ class UserNotProvidedError < RuntimeError
3
+ end
4
+ end
@@ -0,0 +1,62 @@
1
+ require 'posting_service'
2
+ require 'querying_service'
3
+
4
+ module RSimpy
5
+ class Links
6
+ #TODO move this functionality to RSimpy module
7
+ attr_reader :success, :status_code, :status_message
8
+
9
+ def initialize(login=nil, pass=nil)
10
+ if (login && pass)
11
+ @user = RSimpy::User.new login, pass
12
+ else
13
+ @user = get_user_from_file
14
+ end
15
+ end
16
+
17
+ def get_user_from_file
18
+ storage_service = RSimpy::ProfileStorageService.new
19
+ config = RSimpy::Configuration.new storage_service
20
+
21
+ if !config.stored?
22
+ raise UserNotProvidedError "Please configure RSimpy or supply username and password"
23
+ end
24
+
25
+ config.get
26
+ end
27
+
28
+ def save params
29
+ params.add(:accessType, :public) unless params.has_key? :accessType
30
+ execute RSimpy::PostingService.new(RSimpy::SAVE_LINK, RSimpy::Client.new(@user)), params
31
+ end
32
+
33
+ # def get params
34
+ # execute RSimpy::QueryingService.new(RSimpy::GET_LINKS, RSimpy::Client.new(@user)), params
35
+ # end
36
+ #
37
+ # def delete params
38
+ # execute RSimpy::PostingService.new(RSimpy::DELETE_LINK, RSimpy::Client.new(@user)), params
39
+ # end
40
+
41
+
42
+
43
+ def execute service, params
44
+ set_codes
45
+ response = service.execute params
46
+ set_codes service
47
+ response
48
+ end
49
+
50
+ def set_codes service=nil
51
+ if service
52
+ @success = service.success
53
+ @status_code = service.status_code
54
+ @status_message = service.status_message
55
+ else
56
+ @success = false
57
+ @status_code = nil
58
+ @status_message =nil
59
+ end
60
+ end
61
+ end
62
+ end
@@ -0,0 +1,120 @@
1
+ require 'cgi'
2
+
3
+ module RSimpy
4
+ class Parameters
5
+ RSIMPY_SOURCE = 'rsimpy'
6
+
7
+ def initialize params={}
8
+ @params = params
9
+ end
10
+
11
+ def [] key
12
+ @params[key]
13
+ end
14
+
15
+ def []= key, value
16
+ @params[key] = value
17
+ end
18
+
19
+ def has_key? key
20
+ @params.has_key? key
21
+ end
22
+
23
+ def to_querystring
24
+ output = ""
25
+ add_src
26
+
27
+ @params.sort {|a,b| a.to_s<=>b.to_s}.each do |key, value|
28
+ value = format key, value
29
+ value = CGI.escape(value) if value.class == String
30
+ output << "#{key.to_s}=#{value}&"
31
+ end
32
+
33
+ output.chop
34
+ end
35
+
36
+ def add_src
37
+ @params[:src] = RSIMPY_SOURCE unless @params.has_key? :src
38
+ end
39
+
40
+ def format key, value
41
+ case key
42
+ when(:href)
43
+ format_uri(value)
44
+ when(:tags)
45
+ build_tag_string value
46
+ when(:accessType)
47
+ format_access_type value
48
+ else
49
+ value
50
+ end
51
+ end
52
+
53
+ def format_uri uri
54
+ uri = 'http://' + uri unless uri[0..6] == 'http://'
55
+ uri
56
+ end
57
+
58
+ def build_tag_string tags
59
+ if tags.class == Array
60
+ tags.collect{|a| a + ", "}.to_s.chop.chop
61
+ else
62
+ tags
63
+ end
64
+ end
65
+
66
+ def format_access_type type
67
+ type == :private ? 0 : 1
68
+ end
69
+
70
+ def add key, value
71
+ @params[key] = value
72
+ end
73
+
74
+ def title title
75
+ add :title, title
76
+ end
77
+
78
+ def href uri
79
+ add :href, uri
80
+ end
81
+
82
+ def tags tags
83
+ add :tags, tags
84
+ end
85
+
86
+ def access_type type
87
+ add :accessType, type
88
+ end
89
+
90
+ def url_nickname nickname
91
+ add :urlNickname, nickname
92
+ end
93
+
94
+ def note note
95
+ add :note, note
96
+ end
97
+
98
+ def q query
99
+ add :q, query
100
+ end
101
+
102
+ def limit limit
103
+ add :limit, limit
104
+ end
105
+
106
+ def date date, to=nil
107
+ if to
108
+ add :afterDate, format_date(date)
109
+ add :beforeDate, format_date(to)
110
+ else
111
+ add :date, format_date(date)
112
+ end
113
+
114
+ end
115
+
116
+ def format_date date
117
+ date.strftime("%Y-%m-%d")
118
+ end
119
+ end
120
+ end