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,5 @@
1
+ README.rdoc
2
+ lib/**/*.rb
3
+ bin/*
4
+ features/**/*.feature
5
+ LICENSE
@@ -0,0 +1,7 @@
1
+ tmp*
2
+ log*
3
+ *[~#]
4
+ optparse_example.rb
5
+ pkg/*
6
+ coverage*
7
+ nbproject*
data/LICENSE ADDED
@@ -0,0 +1,20 @@
1
+ Copyright (c) 2009 Jamal Hansen
2
+
3
+ Permission is hereby granted, free of charge, to any person obtaining
4
+ a copy of this software and associated documentation files (the
5
+ "Software"), to deal in the Software without restriction, including
6
+ without limitation the rights to use, copy, modify, merge, publish,
7
+ distribute, sublicense, and/or sell copies of the Software, and to
8
+ permit persons to whom the Software is furnished to do so, subject to
9
+ the following conditions:
10
+
11
+ The above copyright notice and this permission notice shall be
12
+ included in all copies or substantial portions of the Software.
13
+
14
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
15
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
16
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
17
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
18
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
19
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
20
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
@@ -0,0 +1,21 @@
1
+ = rsimpy
2
+
3
+ A wrapper around the simpy rest api.
4
+
5
+ == Copyright
6
+
7
+ Copyright (c) 2009 Jamal Hansen. See LICENSE for details.
8
+
9
+ == Todo
10
+
11
+ Watchlists are currently not supported
12
+
13
+ == Examples
14
+
15
+ See examples folder
16
+
17
+ == Configuration
18
+
19
+ To store your Simpy username and config in ~/.rsimpy (not encrypted), you can run the Rake task:
20
+
21
+ rake user:config username=USERNAME password=PASSWORD
@@ -0,0 +1,96 @@
1
+ require 'rubygems'
2
+ require 'rake'
3
+
4
+ begin
5
+ require 'jeweler'
6
+ Jeweler::Tasks.new do |gem|
7
+ gem.name = "rsimpy"
8
+ gem.summary = %Q{API Wrapper for simpy.com}
9
+ gem.email = "jamal.hansen@gmail.com"
10
+ gem.homepage = "http://github.com/rubyyot/rsimpy"
11
+ gem.authors = ["Jamal Hansen"]
12
+ gem.add_dependency('httparty', '>= 0.4.2')
13
+ gem.add_dependency('khayyam', '>= 0.0.1')
14
+ gem.add_development_dependency('cucumber', '>= 0.3.11')
15
+ gem.add_development_dependency('fakeweb', '>= 1.2.3')
16
+ gem.add_development_dependency('shoulda')
17
+ gem.add_development_dependency 'technicalpickles-jeweler'
18
+ gem.rubyforge_project = "rsimpy"
19
+
20
+
21
+ # gem is a Gem::Specification... see http://www.rubygems.org/read/chapter/20 for additional settings
22
+ end
23
+ rescue LoadError
24
+ puts "Jeweler not available. Install it with: sudo gem install technicalpickles-jeweler -s http://gems.github.com"
25
+ end
26
+
27
+ require 'rubygems'
28
+ begin
29
+ require 'cucumber'
30
+ require 'cucumber/rake/task'
31
+
32
+ Cucumber::Rake::Task.new(:features) do |t|
33
+ t.cucumber_opts = "--require features/support/env.rb --require features/links/steps --require features/tags/steps --require features/notes/steps --format pretty"
34
+ end
35
+
36
+ rescue LoadError
37
+ desc 'Cucumber rake task not available'
38
+ task :features do
39
+ abort 'Cucumber rake task is not available. Be sure to install cucumber as a gem or plugin'
40
+ end
41
+ end
42
+
43
+
44
+
45
+ require 'rake/testtask'
46
+ Rake::TestTask.new(:test) do |test|
47
+ test.libs << 'lib' << 'test'
48
+ test.pattern = 'test/**/*_test.rb'
49
+ test.verbose = true
50
+ end
51
+
52
+ begin
53
+ require 'rcov/rcovtask'
54
+ Rcov::RcovTask.new do |test|
55
+ test.libs << 'test'
56
+ test.pattern = 'test/*_test.rb'
57
+ test.verbose = true
58
+ end
59
+ rescue LoadError
60
+ task :rcov do
61
+ abort "RCov is not available. In order to run rcov, you must: sudo gem install spicycode-rcov"
62
+ end
63
+ end
64
+
65
+
66
+ task :default => :test
67
+
68
+ require 'rake/rdoctask'
69
+ Rake::RDocTask.new do |rdoc|
70
+ if File.exist?('VERSION.yml')
71
+ config = YAML.load(File.read('VERSION.yml'))
72
+ version = "#{config[:major]}.#{config[:minor]}.#{config[:patch]}"
73
+ else
74
+ version = ""
75
+ end
76
+
77
+ rdoc.rdoc_dir = 'rdoc'
78
+ rdoc.title = "rsimpy #{version}"
79
+ rdoc.rdoc_files.include('README*')
80
+ rdoc.rdoc_files.include('lib/**/*.rb')
81
+ end
82
+
83
+ namespace :user do
84
+
85
+ desc 'store simpy login in cleartext in your home directory for safekeeping. Use rake user:config login=USERNAME pass=PASSWORD'
86
+ task :config do
87
+ require 'lib/rsimpy'
88
+
89
+ user = RSimpy::User.new ENV['login'], ENV['pass']
90
+ config = RSimpy::Configuration.new RSimpy::ProfileStorageService.new
91
+ config.user = user
92
+ config.save
93
+ end
94
+
95
+ end
96
+
@@ -0,0 +1,4 @@
1
+ ---
2
+ :major: 0
3
+ :minor: 1
4
+ :patch: 2
@@ -0,0 +1,68 @@
1
+ #! /usr/bin/env ruby
2
+
3
+ require 'optparse'
4
+ require 'optparse/time'
5
+ require 'ostruct'
6
+ require 'pp'
7
+ $LOAD_PATH.unshift(File.join(File.dirname(__FILE__), '..', 'lib'))
8
+ require 'rsimpy'
9
+
10
+ class Simp
11
+
12
+
13
+ #
14
+ # Return a structure describing the options.
15
+ #
16
+ def self.parse(args)
17
+ # The options specified on the command line will be collected in *options*.
18
+ # We set default values here.
19
+ options = OpenStruct.new
20
+ options.tags = []
21
+ options.url = ""
22
+ options.title = ""
23
+
24
+ opts = OptionParser.new do |opts|
25
+ opts.banner = "Usage: example.rb [options]"
26
+
27
+ opts.separator ""
28
+ opts.separator "Specific options:"
29
+
30
+ # Mandatory argument.
31
+ opts.on("-l", "--link URL",
32
+ "The url to save") do |url|
33
+ options.url << url
34
+ end
35
+
36
+ # Mandatory argument.
37
+ opts.on("-n", "--name NAME",
38
+ "The url to save") do |title|
39
+ options.title << title
40
+ end
41
+
42
+ # List of arguments.
43
+ opts.on("-t", "--tags foo,bar,baz", Array, "Tags") do |tags|
44
+ options.tags = tags
45
+ end
46
+
47
+ end
48
+
49
+ opts.parse!(args)
50
+ options
51
+ end # parse()
52
+
53
+ end
54
+
55
+ options = Simp.parse(ARGV)
56
+
57
+ begin
58
+ require 'rsimpy'
59
+
60
+ links = RSimpy::Links.new
61
+
62
+ links.save RSimpy::Parameters.new(:href => options.url, :title => options.title, :tags => options.tags)
63
+
64
+ rescue RuntimeError => e
65
+ puts "An error occured."
66
+ pp options
67
+ raise e
68
+ end
@@ -0,0 +1,47 @@
1
+ Feature: Post a link to a simpy account
2
+ In order find a site later
3
+ As a simpy user
4
+ I want to post a link to my simpy account via rsimpy
5
+
6
+ Scenario: Add a link
7
+ Given a user of "USERNAME" with a password of "PASSWORD"
8
+ When the "link" is "http://www.example.com"
9
+ And the "title" is "example"
10
+ And the "accessType" is ":public"
11
+ Then I expect to post the url "http://USERNAME:PASSWORD@www.simpy.com:80/simpy/api/rest/SaveLink.do?accessType=1&link=http%3A%2F%2Fwww.example.com&src=rsimpy&title=example"
12
+ And the response is successful
13
+
14
+ Scenario: Add a private link
15
+ Given a user of "USERNAME" with a password of "PASSWORD"
16
+ When the "link" is "http://www.example.com"
17
+ And the "title" is "example"
18
+ And the "accessType" is ":private"
19
+ Then I expect to post the url "http://USERNAME:PASSWORD@www.simpy.com:80/simpy/api/rest/SaveLink.do?accessType=0&link=http%3A%2F%2Fwww.example.com&src=rsimpy&title=example"
20
+ And the response is successful
21
+
22
+ Scenario: Add a link with a note
23
+ Given a user of "USERNAME" with a password of "PASSWORD"
24
+ When the "link" is "http://www.example.com"
25
+ And the "title" is "example"
26
+ And the "note" is "Examples are good"
27
+ And the "accessType" is ":public"
28
+ Then I expect to post the url "http://USERNAME:PASSWORD@www.simpy.com:80/simpy/api/rest/SaveLink.do?accessType=1&link=http%3A%2F%2Fwww.example.com&note=Examples+are+good&src=rsimpy&title=example"
29
+ And the response is successful
30
+
31
+ Scenario: Add a link with tags
32
+ Given a user of "USERNAME" with a password of "PASSWORD"
33
+ When the "link" is "http://www.example.com"
34
+ And the "title" is "example"
35
+ And the "tags" is "foo, bar, cheese"
36
+ And the "accessType" is ":public"
37
+ Then I expect to post the url "http://USERNAME:PASSWORD@www.simpy.com:80/simpy/api/rest/SaveLink.do?accessType=1&link=http%3A%2F%2Fwww.example.com&src=rsimpy&tags=foo%2C+bar%2C+cheese&title=example"
38
+ And the response is successful
39
+
40
+ Scenario: Add a link with a nickname
41
+ Given a user of "USERNAME" with a password of "PASSWORD"
42
+ When the "link" is "http://www.example.com"
43
+ And the "title" is "example"
44
+ And the "nickname" is "sample"
45
+ And the "accessType" is ":public"
46
+ Then I expect to post the url "http://USERNAME:PASSWORD@www.simpy.com:80/simpy/api/rest/SaveLink.do?accessType=1&link=http%3A%2F%2Fwww.example.com&nickname=sample&src=rsimpy&title=example"
47
+ And the response is successful
@@ -0,0 +1,46 @@
1
+ Feature: Query links from a simpy account
2
+ In order find my bookmarks
3
+ As a simpy user
4
+ I want to query my simpy account via rsimpy
5
+
6
+ Scenario: Basic link query
7
+ Given a user of "USERNAME" with a password of "PASSWORD"
8
+ When I query the user's links
9
+ Then I expect to query the url "http://USERNAME:PASSWORD@www.simpy.com:80/simpy/api/rest/GetLinks.do?src=rsimpy"
10
+ Then the links are returned
11
+ And the response is successful
12
+
13
+ Scenario: Querying a tag
14
+ Given a user of "USERNAME" with a password of "PASSWORD"
15
+ When I query the user's links
16
+ And the "q" is "potato"
17
+ Then I expect to query the url "http://USERNAME:PASSWORD@www.simpy.com:80/simpy/api/rest/GetLinks.do?q=potato&src=rsimpy"
18
+ Then the links are returned
19
+ And the response is successful
20
+
21
+ Scenario: Limiting returned links
22
+ Given a user of "USERNAME" with a password of "PASSWORD"
23
+ When I query the user's links
24
+ And the "limit" is "5"
25
+ Then I expect to query the url "http://USERNAME:PASSWORD@www.simpy.com:80/simpy/api/rest/GetLinks.do?limit=5&src=rsimpy"
26
+ Then the links are returned
27
+ And the response is successful
28
+
29
+ Scenario: Querying a date
30
+ Given a user of "USERNAME" with a password of "PASSWORD"
31
+ When I query the user's links
32
+ And the "date" is "12/21/2008"
33
+ Then I expect to query the url "http://USERNAME:PASSWORD@www.simpy.com:80/simpy/api/rest/GetLinks.do?date=2008-12-21&src=rsimpy"
34
+ Then the links are returned
35
+ And the response is successful
36
+
37
+ Scenario: Querying a date range
38
+ Given a user of "USERNAME" with a password of "PASSWORD"
39
+ When I query the user's links
40
+ And the "beforeDate" is "1/2/2009"
41
+ And the "afterDate" is "1/11/2009"
42
+ Then I expect to query the url "http://USERNAME:PASSWORD@www.simpy.com:80/simpy/api/rest/GetLinks.do?afterDate=2009-01-11&beforeDate=2009-01-02&src=rsimpy"
43
+ Then the links are returned
44
+ And the response is successful
45
+
46
+
@@ -0,0 +1,39 @@
1
+ include Responsive
2
+
3
+ Given /^a user of "([^\"]*)" with a password of "([^\"]*)"$/ do |login, pass|
4
+ FakeWeb.clean_registry
5
+ FakeWeb.allow_net_connect=(false)
6
+
7
+ @client = RSimpy::Client.new(RSimpy::User.new login, pass)
8
+ @p = RSimpy::Parameters.new
9
+ end
10
+
11
+ When /^the "([^\"]*)" is "([^\"]*)"$/ do |key, value|
12
+ @p[key.to_sym] = convert_symbols_and_dates(key, value)
13
+ end
14
+
15
+ Then /^I expect to post the url "([^\"]*)"$/ do |url|
16
+ FakeWeb.register_uri(:post, url, :string => post_response)
17
+
18
+ @service = RSimpy::PostingService.new(RSimpy::SAVE_LINK, @client)
19
+ @response = @service.execute @p
20
+ end
21
+
22
+ Then /^the response is successful$/ do
23
+ assert @service.success
24
+ end
25
+
26
+ When /^I expect to query the url "([^\"]*)"$/ do |url|
27
+ FakeWeb.register_uri(:get, url, :string => get_response)
28
+
29
+ @service = RSimpy::QueryingService.new(RSimpy::GET_LINKS, @client)
30
+ @response = @service.execute @p
31
+ end
32
+
33
+ Then /^the links are returned$/ do
34
+ assert @response.has_key? "links"
35
+ end
36
+
37
+ When /^I query the user's links$/ do
38
+
39
+ end
@@ -0,0 +1,27 @@
1
+ Feature: Query notes from my simpy account
2
+ In order to figure out what I said
3
+ As a simpy user
4
+ I want to query notes from my simpy account via rsimpy
5
+
6
+ Scenario: Querying notes
7
+ Given a user of "USERNAME" with a password of "PASSWORD"
8
+ When I query my notes
9
+ Then I expect to query the notes with the url "http://USERNAME:PASSWORD@www.simpy.com/simpy/api/rest/GetNotes.do?src=rsimpy"
10
+ And notes are returned
11
+ And the response is successful
12
+
13
+ Scenario: Querying notes with keyword
14
+ Given a user of "USERNAME" with a password of "PASSWORD"
15
+ When I query my notes
16
+ And the "q" is "goober"
17
+ Then I expect to query the notes with the url "http://USERNAME:PASSWORD@www.simpy.com/simpy/api/rest/GetNotes.do?q=goober&src=rsimpy"
18
+ And notes are returned
19
+ And the response is successful
20
+
21
+ Scenario: Querying notes with limit
22
+ Given a user of "USERNAME" with a password of "PASSWORD"
23
+ When I query my notes
24
+ And the "limit" is "1"
25
+ Then I expect to query the notes with the url "http://USERNAME:PASSWORD@www.simpy.com/simpy/api/rest/GetNotes.do?limit=1&src=rsimpy"
26
+ And notes are returned
27
+ And the response is successful
@@ -0,0 +1,11 @@
1
+ Feature: Remove note from my simpy account
2
+ In order to clean up my simpy account
3
+ As a simpy user
4
+ I want to remove a note from my simpy account via rsimpy
5
+
6
+ Scenario: Removing a note
7
+ Given a user of "USERNAME" with a password of "PASSWORD"
8
+ When I remove a user's note
9
+ And the "noteId" is "1234"
10
+ Then I expect to remove the note with the url "http://USERNAME:PASSWORD@www.simpy.com/simpy/api/rest/DeleteNote.do?noteId=1234&src=rsimpy"
11
+ Then the response is successful
@@ -0,0 +1,36 @@
1
+ Feature: Save note to my simpy account
2
+ In order to remember something
3
+ As a simpy user
4
+ I want to save a note to my simpy account via rsimpy
5
+
6
+ Scenario: Saving a note
7
+ Given a user of "USERNAME" with a password of "PASSWORD"
8
+ When I save a user's note
9
+ And the "title" is "short note"
10
+ Then I expect to save the note with the url "http://USERNAME:PASSWORD@www.simpy.com/simpy/api/rest/SaveNote.do?title=short+note&src=rsimpy"
11
+ And the response is successful
12
+
13
+ Scenario: Updating a note
14
+ Given a user of "USERNAME" with a password of "PASSWORD"
15
+ And I have a note with the noteId of 1234
16
+ When I update a user's note
17
+ And the "title" is "short note"
18
+ And the "noteId" is "1234"
19
+ Then I expect to update the note with the url "http://USERNAME:PASSWORD@www.simpy.com/simpy/api/rest/SaveNote.do?noteId=1234&title=short+note&src=rsimpy"
20
+ And the response is successful
21
+
22
+ Scenario: Saving a tagged note
23
+ Given a user of "USERNAME" with a password of "PASSWORD"
24
+ When I update a user's note
25
+ And the "title" is "short note"
26
+ And the "tags" is "foo, bar"
27
+ Then I expect to update the note with the url "http://USERNAME:PASSWORD@www.simpy.com/simpy/api/rest/SaveNote.do?tags=foo%2C+bar&title=short+note&src=rsimpy"
28
+ And the response is successful
29
+
30
+ Scenario: Saving a note with a description
31
+ Given a user of "USERNAME" with a password of "PASSWORD"
32
+ When I update a user's note
33
+ And the "title" is "short note"
34
+ And the "description" is "thrilling"
35
+ Then I expect to update the note with the url "http://USERNAME:PASSWORD@www.simpy.com/simpy/api/rest/SaveNote.do?description=thrilling&title=short+note&src=rsimpy"
36
+ And the response is successful
@@ -0,0 +1,46 @@
1
+ include Responsive
2
+
3
+ When /^I ([^\"]*) a user's note$/ do |verb|
4
+
5
+ end
6
+
7
+ Then /^I expect to remove the note with the url "([^\"]*)"$/ do |url|
8
+ FakeWeb.register_uri(:post, url, :string => note_removing_response)
9
+
10
+ @service = RSimpy::PostingService.new(RSimpy::DELETE_NOTE, @client)
11
+ @response = @service.execute @p
12
+ end
13
+
14
+ Then /^I expect to save the note with the url "([^\"]*)"$/ do |url|
15
+ FakeWeb.register_uri(:post, url, :string => note_saving_response)
16
+
17
+ @service = RSimpy::PostingService.new(RSimpy::SAVE_NOTE, @client)
18
+ @response = @service.execute @p
19
+ end
20
+
21
+ Given /^I have a note with the noteId of 1234$/ do
22
+
23
+ end
24
+
25
+ Then /^I expect to update the note with the url "([^\"]*)"$/ do |url|
26
+ FakeWeb.register_uri(:post, url, :string => note_saving_response)
27
+
28
+ @service = RSimpy::PostingService.new(RSimpy::SAVE_NOTE, @client)
29
+ @response = @service.execute @p
30
+ end
31
+
32
+ When /^I query my notes$/ do
33
+
34
+ end
35
+
36
+ Then /^I expect to query the notes with the url "([^\"]*)"$/ do |url|
37
+ FakeWeb.register_uri(:get, url, :string => note_querying_response)
38
+
39
+ @service = RSimpy::QueryingService.new(RSimpy::GET_NOTES, @client)
40
+ @response = @service.execute @p
41
+ end
42
+
43
+ Then /^notes are returned$/ do
44
+ assert @response.has_key? 'notes'
45
+ end
46
+