rentlinx 0.9.0 → 0.9.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (33) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +37 -16
  3. data/lib/rentlinx.rb +19 -0
  4. data/lib/rentlinx/client.rb +24 -0
  5. data/lib/rentlinx/default.rb +1 -0
  6. data/lib/rentlinx/errors.rb +20 -0
  7. data/lib/rentlinx/models/base.rb +46 -8
  8. data/lib/rentlinx/models/property.rb +25 -0
  9. data/lib/rentlinx/models/property_amenity.rb +4 -0
  10. data/lib/rentlinx/models/property_link.rb +4 -0
  11. data/lib/rentlinx/models/property_photo.rb +4 -0
  12. data/lib/rentlinx/models/unit.rb +14 -0
  13. data/lib/rentlinx/models/unit_amenity.rb +1 -0
  14. data/lib/rentlinx/models/unit_link.rb +1 -0
  15. data/lib/rentlinx/models/unit_photo.rb +1 -0
  16. data/lib/rentlinx/modules/amenity_client_methods.rb +24 -0
  17. data/lib/rentlinx/modules/amenityable.rb +23 -0
  18. data/lib/rentlinx/modules/link_client_methods.rb +24 -0
  19. data/lib/rentlinx/modules/linkable.rb +12 -0
  20. data/lib/rentlinx/modules/photo_client_methods.rb +3 -0
  21. data/lib/rentlinx/modules/photoable.rb +4 -0
  22. data/lib/rentlinx/modules/property_client_methods.rb +5 -0
  23. data/lib/rentlinx/modules/unit_client_methods.rb +1 -0
  24. data/lib/rentlinx/validators/address_validator.rb +13 -0
  25. data/lib/rentlinx/validators/attribute_processor_service.rb +20 -1
  26. data/lib/rentlinx/validators/base_validator.rb +12 -0
  27. data/lib/rentlinx/validators/city_validator.rb +3 -0
  28. data/lib/rentlinx/validators/phone_validator.rb +2 -0
  29. data/lib/rentlinx/validators/state_validator.rb +3 -0
  30. data/lib/rentlinx/validators/url_validator.rb +1 -0
  31. data/lib/rentlinx/validators/zip_validator.rb +1 -0
  32. data/lib/rentlinx/version.rb +3 -1
  33. metadata +4 -4
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 6945492920d30e62b769a7b4b3c89b1e26e7be10
4
- data.tar.gz: 07f11c4486e4e142632277a28fffa4a0b1e33573
3
+ metadata.gz: cedfa421e0893f1fb8ece12bd133929b75107c85
4
+ data.tar.gz: d2de51edd47f047a7244efa188e406b237ea964d
5
5
  SHA512:
6
- metadata.gz: d72733d83b47e0bd1141b2c06d36d4ad19fe04e4e3b9d6469d8612211eb2a6ba8448a3fdf2adcc666cc2a2fa670d484a209db8f4fe4925a7f1ea4b6ba2342c83
7
- data.tar.gz: 1cf99840f44b1c2f9ae1a86e99eddf16ec351cedddd7ee6c52c516542d2dd66330c06265dbac60435e367bcb5ae57637479b8ada6d4c2a71b11e5a7ba7b0a493
6
+ metadata.gz: 9c22c7e3ed1751a8863519d5b02563db53b47f939e6a9bfa39e87fb1a2453d2e16cc2d207da897b3dcc94274c0fe3c664b504bbf95bd0ad639acd4c9924a5824
7
+ data.tar.gz: 2f6c08a6f4643ba3b5c78c588d235fb6490fb7beeba556b7c2790b647a3b296d17e942235c613427a17e5354896e094550eecb69aa968c6110a572df403e0cf5
data/README.md CHANGED
@@ -9,8 +9,39 @@ _rentlinx_client_ is a ruby wrapper for the RentLinx API.
9
9
 
10
10
  ## Installation
11
11
 
12
+ To install from the command line, run:
13
+
12
14
  gem install rentlinx
13
15
 
16
+ To include in a rails app, include this line in your gemfile:
17
+
18
+ gem 'rentlinx'
19
+
20
+ ### Usage
21
+
22
+ Configure like so:
23
+
24
+ Rentlinx.configure do |rentlinx|
25
+ rentlinx.username ENV['RENTLINX_USERNAME']
26
+ rentlinx.password ENV['RENTLINX_PASSWORD']
27
+ rentlinx.site_url 'https://rentlinx.com/api/v2'
28
+ rentlinx.log_level :error
29
+ end
30
+
31
+ For all endpoints, attributes are defined by the API: https://www.rentlinx.com/mongoose/help
32
+
33
+ Properties:
34
+
35
+ prop = Property.new(attributes)
36
+ prop.post # creates
37
+
38
+ prop.website = 'http://example.com'
39
+ prop.post # updates
40
+
41
+ prop = Property.from_id('property-id') # fetches
42
+
43
+ Objects can be created for all endpoints supported by the Rentlinx API, including Units, Amenities, Photos, and Links. For more detailed information, see the [full documentation on rubygems](http://www.rubydoc.info/gems/rentlinx).
44
+
14
45
  ## Contributing and development
15
46
 
16
47
  Pull requests are welcome for this gem. New features require writing new
@@ -36,6 +67,12 @@ Not all rubocop's rules are set in stone, so once you are receiving only
36
67
  warnings testing rules that may not make sense, please comment on your pull
37
68
  request indicating you think the rules should be adjusted with your reasoning.
38
69
 
70
+ ### Documentation
71
+
72
+ All new classes, modules, and public methods should be documented in the style
73
+ of [yard](http://yardoc.org/). Modified classes and methods should have their
74
+ documentation updated accordingly. Tests do not need documentation.
75
+
39
76
  ### Testing: Unit tests
40
77
 
41
78
  The second suite is running minitest. The simplest way to invoke our minitest
@@ -48,22 +85,6 @@ test files can be executed via:
48
85
 
49
86
  ruby -Ilib:test test/FILENAME.rb
50
87
 
51
-
52
- ### Usage
53
-
54
- For all endpoints, attributes are defined by the API: https://www.rentlinx.com/mongoose/help
55
-
56
- Properties can be created, updated, and fetched from Rentlinx like so:
57
-
58
- prop = Property.new(attributes)
59
- prop.post # creates
60
-
61
- prop.website = 'http://example.com'
62
- prop.post # updates
63
-
64
- prop = Property.from_id('property-id') # fetches
65
-
66
-
67
88
  ## Copyright and license
68
89
 
69
90
  Source released under the Simplified BSD License.
data/lib/rentlinx.rb CHANGED
@@ -11,16 +11,29 @@ require 'rentlinx/models/unit_amenity'
11
11
  require 'rentlinx/models/property_link'
12
12
  require 'rentlinx/models/unit_link'
13
13
 
14
+ # This is the main rentlinx module. All Rentlinx objects
15
+ # and methods are namespaced under this module.
14
16
  module Rentlinx
15
17
  @username = nil
16
18
  @password = nil
17
19
  @site_url = nil
18
20
 
19
21
  class << self
22
+ # Allows the configuration of Rentlinx in a configure-block
23
+ # style.
24
+ #
25
+ # @example
26
+ # Rentlinx.configure do |rentlinx|
27
+ # rentlinx.username ENV['RENTLINX_USERNAME']
28
+ # rentlinx.password ENV['RENTLINX_PASSWORD']
29
+ # rentlinx.site_url 'https://rentlinx.com/api/v2'
30
+ # rentlinx.log_level :error
31
+ # end
20
32
  def configure(&block)
21
33
  block.call(self)
22
34
  end
23
35
 
36
+ # Sets and retrieves the username used to log in to Rentlinx
24
37
  def username(*args)
25
38
  if args.empty?
26
39
  @username
@@ -29,6 +42,7 @@ module Rentlinx
29
42
  end
30
43
  end
31
44
 
45
+ # Sets and retrieves the password used to log in to Rentlinx
32
46
  def password(*args)
33
47
  if args.empty?
34
48
  @password
@@ -37,6 +51,7 @@ module Rentlinx
37
51
  end
38
52
  end
39
53
 
54
+ # Sets and retrieves the URL where the API is hosted.
40
55
  def site_url(*args)
41
56
  if args.empty?
42
57
  @site_url
@@ -45,6 +60,8 @@ module Rentlinx
45
60
  end
46
61
  end
47
62
 
63
+ # Sets and retrieves the log level, currently only :error
64
+ # and :debug are supported
48
65
  def log_level(*args)
49
66
  if args.empty?
50
67
  @log_level
@@ -53,10 +70,12 @@ module Rentlinx
53
70
  end
54
71
  end
55
72
 
73
+ # The client object used for communicating with Rentlinx
56
74
  def client
57
75
  @client ||= Rentlinx::Client.new
58
76
  end
59
77
 
78
+ # The logger object
60
79
  def logger
61
80
  lgr = Logging.logger(STDOUT)
62
81
  lgr.level = (@log_level || :error)
@@ -9,6 +9,11 @@ require 'rentlinx/modules/amenity_client_methods'
9
9
  require 'rentlinx/modules/link_client_methods'
10
10
 
11
11
  module Rentlinx
12
+ # This class and its included modules encapsulate all
13
+ # communication directly with the Rentlinx API.
14
+ #
15
+ # It should not be interacted with, the objects provide
16
+ # all the functionality necessary to work with Rentlinx.
12
17
  class Client
13
18
  include Rentlinx::PropertyClientMethods
14
19
  include Rentlinx::UnitClientMethods
@@ -16,6 +21,14 @@ module Rentlinx
16
21
  include Rentlinx::AmenityClientMethods
17
22
  include Rentlinx::LinkClientMethods
18
23
 
24
+ # Returns a new instance of client. Avoid using.
25
+ #
26
+ # Note that the method {Rentlinx.client} initializes and caches
27
+ # an instance of the Rentlinx client. This method should be used
28
+ # instead of this one when interacting directly with the client
29
+ # to avoid making multiple connections to Rentlinx.
30
+ #
31
+ # Rentlinx must be configured before invoking this method.
19
32
  def initialize
20
33
  raise Rentlinx::NotConfigured if Rentlinx.username.nil? ||
21
34
  Rentlinx.password.nil? ||
@@ -25,6 +38,9 @@ module Rentlinx
25
38
  @api_token ||= authenticate(Rentlinx.username, Rentlinx.password)
26
39
  end
27
40
 
41
+ # Pushes an object's attributes out to Rentlinx
42
+ #
43
+ # @param object [Rentlinx::Base] the object to be posted
28
44
  def post(object)
29
45
  case object
30
46
  when Rentlinx::Property
@@ -38,6 +54,10 @@ module Rentlinx
38
54
  end
39
55
  end
40
56
 
57
+ # Unposts an object from Rentlinx
58
+ #
59
+ # @param type [Symbol] the type of object to be unposted
60
+ # @param id [String] the rentlinx id of the object to be unposted
41
61
  def unpost(type, id)
42
62
  case type
43
63
  when :property
@@ -49,6 +69,10 @@ module Rentlinx
49
69
  end
50
70
  end
51
71
 
72
+ # Pulls the attributes for an object from Rentlinx and instantiates it
73
+ #
74
+ # @param type [Symbol] the type of object to be fetched
75
+ # @param id [String] the rentlinx id of the object to be fetched
52
76
  def get(type, id)
53
77
  case type
54
78
  when :property
@@ -1,6 +1,7 @@
1
1
  require 'rentlinx/version'
2
2
 
3
3
  module Rentlinx
4
+ # The default headers for the Rentlinx client
4
5
  module Default
5
6
  USER_AGENT = "Rentlinx Ruby Client #{Rentlinx::VERSION}".freeze
6
7
 
@@ -1,33 +1,48 @@
1
1
  require 'json'
2
2
 
3
3
  module Rentlinx
4
+ # Basic error class to be inherited from
5
+ #
6
+ # Use this error to rescue all types of Rentlinx errors
4
7
  class RentlinxError < StandardError
5
8
  end
6
9
 
10
+ # Thrown when instantiating an object with attributes
11
+ # that object does not support them
7
12
  class UnexpectedAttributes < RentlinxError
8
13
  end
9
14
 
15
+ # Thrown when posting or getting an invalid type
10
16
  class InvalidTypeParam < RentlinxError
11
17
  end
12
18
 
19
+ # Thrown when the Rentlinx client is initialized without first
20
+ # being configured
13
21
  class NotConfigured < RentlinxError
14
22
  def initialize
15
23
  super('Rentlinx is not configured.')
16
24
  end
17
25
  end
18
26
 
27
+ # Thrown when an object that does not pass validation tries
28
+ # to post or update
19
29
  class InvalidObject < RentlinxError
20
30
  def initialize(object)
21
31
  super("#{object.class} is invalid: #{object.error_messages}")
22
32
  end
23
33
  end
24
34
 
35
+ # Thrown when a group of objects is passed to a batch endpoint but
36
+ # cannot be posted because they belong to different properties
25
37
  class IncompatibleGroupOfObjectsForPost < RentlinxError
26
38
  def initialize(property)
27
39
  super("These objects cannot be grouped together ('#{property}' differ).")
28
40
  end
29
41
  end
30
42
 
43
+ # A general class of errors for handling issues in the communication with
44
+ # Rentlinx. To be inherited from, or thrown when the server returns a code
45
+ # not otherwise handled.
31
46
  class HTTPError < RentlinxError
32
47
  attr_reader :response
33
48
 
@@ -37,6 +52,7 @@ module Rentlinx
37
52
  end
38
53
  end
39
54
 
55
+ # Thrown when error code 400 (bad request) is received
40
56
  class BadRequest < HTTPError
41
57
  def initialize(response)
42
58
  default_message = 'The request sent to the server was invalid.'
@@ -49,24 +65,28 @@ module Rentlinx
49
65
  end
50
66
  end
51
67
 
68
+ # Thrown when error code 404 (not found) is received
52
69
  class NotFound < HTTPError
53
70
  def initialize(response)
54
71
  super(response, 'The item you requested could not be found on the remote server.')
55
72
  end
56
73
  end
57
74
 
75
+ # Thrown when error code 409 (conflict) is received
58
76
  class Conflict < HTTPError
59
77
  def initialize(response)
60
78
  super(response, 'There was a conflict on the remote server.')
61
79
  end
62
80
  end
63
81
 
82
+ # Thrown when error code 403 (forbidden) is received
64
83
  class Forbidden < HTTPError
65
84
  def initialize(response)
66
85
  super(response, 'You are not permitted to access the item you requested.')
67
86
  end
68
87
  end
69
88
 
89
+ # Thrown when 500 series error codes (internal server errors) are received
70
90
  class ServerError < HTTPError
71
91
  def initialize(response)
72
92
  super(response, 'The remote server has experienced an error.')
@@ -1,7 +1,20 @@
1
1
  require 'rentlinx/validators/attribute_processor_service'
2
2
 
3
3
  module Rentlinx
4
+ # This is the class on which all other Rentlinx classes are based,
5
+ # it encapsulates much of the important logic used by every class.
6
+ #
7
+ # It should never be instantiated on its own, use one of its
8
+ # subclasses.
4
9
  class Base
10
+ # Creates a new instance of the class, but the base class should
11
+ # never be directly instantiated.
12
+ #
13
+ # This method takes in the attributes for the new instance, runs
14
+ # them through the {AttributeProcessor} and saves them as instance
15
+ # variables.
16
+ #
17
+ # @param attrs [Hash] a hash of attributes to save.
5
18
  def initialize(attrs)
6
19
  @processor = AttributeProcessor.new(attrs.dup)
7
20
  attrs = @processor.process
@@ -12,30 +25,41 @@ module Rentlinx
12
25
  raise UnexpectedAttributes, "Unexpected Attributes: #{remaining_attrs.join(', ')}" if remaining_attrs.compact.size > 0
13
26
  end
14
27
 
28
+ # Provides a list of attributes supported by the class.
29
+ #
30
+ # @return an array of attribute keys
15
31
  def attributes
16
32
  self.class::ATTRIBUTES
17
33
  end
18
34
 
35
+ # Provides the list of required attributes for the class (a subset of Class.attributes)
36
+ #
37
+ # @return an array of attribute keys
19
38
  def required_attributes
20
39
  self.class::REQUIRED_ATTRIBUTES
21
40
  end
22
41
 
42
+ # Sends the object to Rentlinx
43
+ #
44
+ # @example
45
+ # prop = Rentlinx::Property.new(attrs)
46
+ # prop.post
23
47
  def post
24
48
  Rentlinx.client.post(self)
25
49
  end
26
50
 
51
+ # Removes the object from Rentlinx
52
+ #
53
+ # @example
54
+ # prop = Rentlinx::Property.new(attrs)
55
+ # prop.unpost
27
56
  def unpost
28
57
  Rentlinx.client.unpost(type, send(type.to_s + 'ID'))
29
58
  end
30
59
 
31
- def self.unpost(id)
32
- Rentlinx.client.unpost(type, id)
33
- end
34
-
35
- def self.get_from_id(type, id)
36
- Rentlinx.client.get(type.to_sym, id)
37
- end
38
-
60
+ # Converts the object to a hash
61
+ #
62
+ # @return a hash including the attributes and values
39
63
  def to_hash
40
64
  {}.tap do |hash|
41
65
  attributes.each do |at|
@@ -44,10 +68,16 @@ module Rentlinx
44
68
  end
45
69
  end
46
70
 
71
+ # Determines the validity of the object
72
+ #
73
+ # @return true if valid, false if invalid
47
74
  def valid?
48
75
  error_messages.empty?
49
76
  end
50
77
 
78
+ # Provides error messages on invalid objects
79
+ #
80
+ # @return a hash of error messages
51
81
  def error_messages
52
82
  @processor = AttributeProcessor.new(to_hash)
53
83
  @processor.process
@@ -63,6 +93,14 @@ module Rentlinx
63
93
 
64
94
  private
65
95
 
96
+ def self.unpost(id)
97
+ Rentlinx.client.unpost(type, id)
98
+ end
99
+
100
+ def self.get_from_id(type, id)
101
+ Rentlinx.client.get(type.to_sym, id)
102
+ end
103
+
66
104
  def type
67
105
  self.class.type
68
106
  end
@@ -3,6 +3,7 @@ require 'rentlinx/modules/amenityable'
3
3
  require 'rentlinx/modules/linkable'
4
4
 
5
5
  module Rentlinx
6
+ # An object that represents a Rentlinx property.
6
7
  class Property < Base
7
8
  ATTRIBUTES = [:companyID, :propertyID, :description, :address, :city, :state,
8
9
  :zip, :marketingName, :hideAddress, :latitude, :longitude,
@@ -15,15 +16,29 @@ module Rentlinx
15
16
 
16
17
  attr_accessor(*ATTRIBUTES)
17
18
 
19
+ # Posts the property with all of its attached units.
20
+ #
21
+ # TODO: Discuss whether or not these kinds of methods are needed,
22
+ # or whether we should have post do everything every time.
18
23
  def post_with_units
19
24
  post
20
25
  units.each(&:post) unless units.nil? || units.empty?
21
26
  end
22
27
 
28
+ # The list of units attached to the property.
29
+ #
30
+ # If the units list is empty, it will query Rentlinx for the list
31
+ # of units stored on their end.
32
+ #
33
+ # @return a list of Rentlinx::Unit objects
23
34
  def units
24
35
  @units ||= get_units_for_property_id(propertyID)
25
36
  end
26
37
 
38
+ # Allows assigning a list of units to the property.
39
+ #
40
+ # @param unit_list [Array] a list of Rentlinx::Unit objects
41
+ # @return the updated list of Rentlinx::Unit objects
27
42
  def units=(unit_list)
28
43
  @units = unit_list.map do |unit|
29
44
  unit.propertyID = propertyID
@@ -31,21 +46,31 @@ module Rentlinx
31
46
  end
32
47
  end
33
48
 
49
+ # Queries rentlinx and builds a property with the given ID.
50
+ #
51
+ # The returned property will have all the attributes Rentlinx
52
+ # has for the property on their end.
53
+ #
54
+ # @param id [String] the rentlinx id of the property
55
+ # @return a Rentlinx::Property that is up to date with the remote one
34
56
  def self.from_id(id)
35
57
  get_from_id(:property, id)
36
58
  end
37
59
 
38
60
  include Rentlinx::Photoable
61
+ # For internal use.
39
62
  def photo_class
40
63
  Rentlinx::PropertyPhoto
41
64
  end
42
65
 
43
66
  include Rentlinx::Amenityable
67
+ # For internal use.
44
68
  def amenity_class
45
69
  Rentlinx::PropertyAmenity
46
70
  end
47
71
 
48
72
  include Rentlinx::Linkable
73
+ # For internal use.
49
74
  def link_class
50
75
  Rentlinx::PropertyLink
51
76
  end
@@ -1,4 +1,5 @@
1
1
  module Rentlinx
2
+ # An amenity on a propery
2
3
  class PropertyAmenity < Base
3
4
  ATTRIBUTES = [:details, :name, :propertyID]
4
5
 
@@ -6,6 +7,9 @@ module Rentlinx
6
7
 
7
8
  attr_accessor(*ATTRIBUTES)
8
9
 
10
+ # Converts the object to a hash
11
+ #
12
+ # @return a hash with the details and name of the link
9
13
  def to_hash
10
14
  { details: details, name: name }
11
15
  end
@@ -1,4 +1,5 @@
1
1
  module Rentlinx
2
+ # A link on a property
2
3
  class PropertyLink < Base
3
4
  ATTRIBUTES = [:propertyID, :title, :url]
4
5
 
@@ -6,6 +7,9 @@ module Rentlinx
6
7
 
7
8
  attr_accessor(*ATTRIBUTES)
8
9
 
10
+ # Converts the link to a hash
11
+ #
12
+ # @return a hash with the url and title of the link
9
13
  def to_hash
10
14
  { url: url, title: title }
11
15
  end
@@ -1,4 +1,5 @@
1
1
  module Rentlinx
2
+ # A photo on a property
2
3
  class PropertyPhoto < Base
3
4
  ATTRIBUTES = [:url, :caption, :position, :propertyID, :unitID]
4
5
 
@@ -6,6 +7,9 @@ module Rentlinx
6
7
 
7
8
  attr_accessor(*ATTRIBUTES)
8
9
 
10
+ # Converts the photo to a hash
11
+ #
12
+ # @return a hash with the url and caption of the photo
9
13
  def to_hash
10
14
  { url: url, caption: caption }
11
15
  end
@@ -3,6 +3,7 @@ require 'rentlinx/modules/amenityable'
3
3
  require 'rentlinx/modules/linkable'
4
4
 
5
5
  module Rentlinx
6
+ # An object that represents a Rentlinx unit.
6
7
  class Unit < Base
7
8
  ATTRIBUTES = [:unitID, :propertyID, :name, :description, :rent, :maxRent,
8
9
  :deposit, :maxDeposit, :squareFeet, :maxSquareFeet,
@@ -16,24 +17,37 @@ module Rentlinx
16
17
  attr_accessor(*ATTRIBUTES)
17
18
 
18
19
  include Rentlinx::Photoable
20
+ # For internal use
19
21
  def photo_class
20
22
  Rentlinx::UnitPhoto
21
23
  end
22
24
 
23
25
  include Rentlinx::Amenityable
26
+ # For internal use
24
27
  def amenity_class
25
28
  Rentlinx::UnitAmenity
26
29
  end
27
30
 
28
31
  include Rentlinx::Linkable
32
+ # For internal use
29
33
  def link_class
30
34
  Rentlinx::UnitLink
31
35
  end
32
36
 
37
+ # Gets all the photos for a unit.
38
+ #
39
+ # @return a list of Rentlinx::UnitPhoto objects
33
40
  def photos
34
41
  super.select { |p| p.unitID == unitID }
35
42
  end
36
43
 
44
+ # Queries rentlinx and builds a unit with the given ID
45
+ #
46
+ # The returned unit will have all the attributes Rentlinx
47
+ # has for the unit on their end.
48
+ #
49
+ # @param id [String] the rentlinx id of the unit
50
+ # @return a Rentlinx::Unit that is up to date with the remote one
37
51
  def self.from_id(id)
38
52
  get_from_id(:unit, id)
39
53
  end
@@ -1,4 +1,5 @@
1
1
  module Rentlinx
2
+ # An amenity on a unit
2
3
  class UnitAmenity < PropertyAmenity
3
4
  ATTRIBUTES += [:unitID]
4
5
 
@@ -1,4 +1,5 @@
1
1
  module Rentlinx
2
+ # A link on a unit
2
3
  class UnitLink < PropertyLink
3
4
  ATTRIBUTES += [:unitID]
4
5
 
@@ -1,4 +1,5 @@
1
1
  module Rentlinx
2
+ # A photo on a unit
2
3
  class UnitPhoto < PropertyPhoto
3
4
  REQUIRED_ATTRIBUTES += [:unitID]
4
5
  end
@@ -1,5 +1,11 @@
1
1
  module Rentlinx
2
+ # Client methods for amenities
3
+ #
4
+ # TODO: Refactor into AttachmentClientMethods
2
5
  module AmenityClientMethods
6
+ # Submits amenities to the batch endpoint on Rentlinx
7
+ #
8
+ # @param amenities [Array] an array of amenity objects
3
9
  def post_amenities(amenities)
4
10
  return if amenities.nil?
5
11
  raise(Rentlinx::InvalidObject, amenities.find { |a| !a.valid? }) unless amenities.all?(&:valid?)
@@ -12,6 +18,11 @@ module Rentlinx
12
18
  post_unit_amenities(unit_amenities) unless unit_amenities.empty?
13
19
  end
14
20
 
21
+ # Unposts all amenities for a unit or property by posting
22
+ # an empty list to the batch update endpoint.
23
+ #
24
+ # @param object [Rentlinx::Property, Rentlinx::Unit] the object
25
+ # whos amenities should be unposted
15
26
  def unpost_amenities_for(object)
16
27
  case object
17
28
  when Rentlinx::Unit
@@ -23,6 +34,11 @@ module Rentlinx
23
34
  end
24
35
  end
25
36
 
37
+ # Gets all the amenities for a property, dividing them into
38
+ # {Rentlinx::PropertyAmenity} and {Rentlinx::UnitAmenity} objects
39
+ #
40
+ # @param id [String] an ID for a property posted to Rentlinx
41
+ # @return an array of unit and property amenities
26
42
  def get_amenities_for_property_id(id)
27
43
  data = request('GET', "properties/#{id}/amenities")['data']
28
44
  data.map do |amenity_data|
@@ -37,11 +53,19 @@ module Rentlinx
37
53
  return []
38
54
  end
39
55
 
56
+ # Gets all the amenities for a unit
57
+ #
58
+ # @param unit [Rentlinx::Unit] the unit to fetch amenities for
59
+ # @return an array of unit amenities
40
60
  def get_amenities_for_unit(unit)
41
61
  amenities = get_amenities_for_property_id(unit.propertyID)
42
62
  amenities.select { |a| defined? a.unitID && a.unitID == unit.unitID }
43
63
  end
44
64
 
65
+ # Unposts a single amenity
66
+ #
67
+ # @param amenity [Rentlinx::UnitAmenity, Rentlinx::PropertyAmenity] the
68
+ # amenity to be unposted
45
69
  def unpost_amenity(amenity)
46
70
  case amenity
47
71
  when Rentlinx::UnitAmenity
@@ -1,10 +1,19 @@
1
1
  module Rentlinx
2
+ # A module that encapsulates all ammenity related logic for {Rentlinx::Property} and
3
+ # {Rentlinx::Unit} objects. All of these methods can be called on Properties and Units.
4
+ #
5
+ # TODO: Refactor into BaseAble class along with {Linkable} and {Photoable}
2
6
  module Amenityable
7
+ # Posts the object with its associated amenities
8
+ #
9
+ # TODO: Discuss whether or not these kinds of methods are needed,
10
+ # or whether we should have post do everything every time.
3
11
  def post_with_amenities
4
12
  post
5
13
  post_amenities
6
14
  end
7
15
 
16
+ # Posts the object's amenities
8
17
  def post_amenities
9
18
  return if @amenities.nil?
10
19
 
@@ -15,6 +24,9 @@ module Rentlinx
15
24
  end
16
25
  end
17
26
 
27
+ # Loads and caches the list of amenities from Rentlinx.
28
+ #
29
+ # @return a list of amenities
18
30
  def amenities
19
31
  return @amenities if @amenities
20
32
 
@@ -26,6 +38,10 @@ module Rentlinx
26
38
  end
27
39
  end
28
40
 
41
+ # Allows assignment of amenities to the object.
42
+ #
43
+ # @param amenity_list [Array] an array of amenities
44
+ # @return the list of amenities on the object
29
45
  def amenities=(amenity_list)
30
46
  @amenities = amenity_list.map do |amenity|
31
47
  amenity.propertyID = propertyID
@@ -34,6 +50,13 @@ module Rentlinx
34
50
  end
35
51
  end
36
52
 
53
+ # Builds a single amenity and attaches it to the object. This method
54
+ # conveniently assigns the propertyID and unitID (if present) of the
55
+ # parent object, so these need not be passed.
56
+ #
57
+ # @param options [Hash] the attributes for the amenity, defined in
58
+ # {Rentlinx::PropertyAmenity}
59
+ # @return the updated list of amenities on the object
37
60
  def add_amenity(options)
38
61
  options.merge!(propertyID: propertyID)
39
62
  options.merge!(unitID: unitID) if defined? unitID
@@ -1,5 +1,15 @@
1
1
  module Rentlinx
2
+ # Client methods for Amenities
3
+ #
4
+ # TODO: Refactor into AttachmentClientMethods
2
5
  module LinkClientMethods
6
+ # Posts an array of links to Rentlinx
7
+ #
8
+ # This uses the batch endpoint, so all links must be associated with
9
+ # the same property. They can be on different units, so long as all units
10
+ # are on the same property.
11
+ #
12
+ # @param links [Array] an array of links which all have the same propertyID
3
13
  def post_links(links)
4
14
  return if links.nil?
5
15
 
@@ -13,6 +23,11 @@ module Rentlinx
13
23
  post_unit_links(unit_links) unless unit_links.empty?
14
24
  end
15
25
 
26
+ # Unposts all links for unit or property by posting an empty
27
+ # array to the batch update endpoint
28
+ #
29
+ # @param object [Rentlinx::Property, Rentlinx::Unit] the object whos
30
+ # links should be unposted
16
31
  def unpost_links_for(object)
17
32
  case object
18
33
  when Rentlinx::Unit
@@ -24,6 +39,9 @@ module Rentlinx
24
39
  end
25
40
  end
26
41
 
42
+ # Gets all the links for a given property, including unit links
43
+ #
44
+ # @param id [String] the id of the property
27
45
  def get_links_for_property_id(id)
28
46
  data = request('GET', "properties/#{id}/links")['data']
29
47
  data.map do |link_data|
@@ -38,11 +56,17 @@ module Rentlinx
38
56
  return []
39
57
  end
40
58
 
59
+ # Gets all the links for a given unit
60
+ #
61
+ # @param unit [Rentlinx::Unit] the unit for which links should be fetched
41
62
  def get_links_for_unit(unit)
42
63
  links = get_links_for_property_id(unit.propertyID)
43
64
  links.select { |link| defined?(link.unitID) && link.unitID == unit.unitID }
44
65
  end
45
66
 
67
+ # Unposts a specific link
68
+ #
69
+ # @param link [Rentlinx::UnitLink, Rentlinx::PropertyLink] the link to be unposted
46
70
  def unpost_link(link)
47
71
  case link
48
72
  when Rentlinx::UnitLink
@@ -1,10 +1,19 @@
1
1
  module Rentlinx
2
+ # A module that encapsulates all link related logic for {Rentlinx::Property} and
3
+ # {Rentlinx::Unit} objects. All of these methods can be called on Properties and Units.
4
+ #
5
+ # TODO: Refactor into BaseAble class along with {Amenityable} and {Photoable}
2
6
  module Linkable
7
+ # Posts the object with associated links
8
+ #
9
+ # TODO: Discuss whether or not these kinds of methods are needed,
10
+ # or whether we should have post do everything every time.
3
11
  def post_with_links
4
12
  post
5
13
  post_links
6
14
  end
7
15
 
16
+ # Posts the links for an object
8
17
  def post_links
9
18
  return if @links.nil?
10
19
 
@@ -15,6 +24,9 @@ module Rentlinx
15
24
  end
16
25
  end
17
26
 
27
+ # Loads and caches the list of amenities from Rentlinx.
28
+ #
29
+ # @return a list of amenities
18
30
  def links
19
31
  @links ||=
20
32
  if defined? unitID
@@ -1,4 +1,7 @@
1
1
  module Rentlinx
2
+ # Client methods for photos
3
+ #
4
+ # TODO: Refactor into AttachmentClientMethods
2
5
  module PhotoClientMethods
3
6
  def post_photos(photos)
4
7
  return if photos.nil?
@@ -1,4 +1,8 @@
1
1
  module Rentlinx
2
+ # A module that encapsulates all photo related logic for {Rentlinx::Property} and
3
+ # {Rentlinx::Unit} objects. All of these methods can be called on Properties and Units.
4
+ #
5
+ # TODO: Refactor into BaseAble class along with {Linkable} and {Amenityable}
2
6
  module Photoable
3
7
  def post_with_photos
4
8
  post
@@ -1,5 +1,10 @@
1
1
  module Rentlinx
2
+ # Client methods for property
2
3
  module PropertyClientMethods
4
+ # Gets all the units for a given property id
5
+ #
6
+ # @param id [String] the id of the property
7
+ # @return a list of Rentlinx::Unit objects
3
8
  def get_units_for_property_id(id)
4
9
  data = request('GET', "properties/#{id}/units")['data']
5
10
  data.map do |unit_data|
@@ -1,4 +1,5 @@
1
1
  module Rentlinx
2
+ # Client methods for units. No public methods.
2
3
  module UnitClientMethods
3
4
  private
4
5
 
@@ -0,0 +1,13 @@
1
+ module Rentlinx
2
+ # Validator for addresses
3
+ #
4
+ # Ensures they are three or more characters.
5
+ class AddressValidator < BaseValidator
6
+ private
7
+
8
+ def validate
9
+ return if !@value.nil? && @value.length > 2
10
+ @error = "'#{@value}' is not a valid address, an address must be 3 characters or more."
11
+ end
12
+ end
13
+ end
@@ -1,4 +1,5 @@
1
1
  require 'rentlinx/validators/base_validator'
2
+ require 'rentlinx/validators/address_validator'
2
3
  require 'rentlinx/validators/city_validator'
3
4
  require 'rentlinx/validators/phone_validator'
4
5
  require 'rentlinx/validators/state_validator'
@@ -6,22 +7,37 @@ require 'rentlinx/validators/url_validator'
6
7
  require 'rentlinx/validators/zip_validator'
7
8
 
8
9
  module Rentlinx
10
+ # Provides processing and validation for attributes on {Rentlinx::Property} and
11
+ # {Rentlinx::Unit} objects
9
12
  class AttributeProcessor
10
13
  attr_reader :errors
11
14
  attr_reader :processed_attrs
12
15
 
16
+ # @param attrs [Hash] the attributes to be processed
13
17
  def initialize(attrs)
14
18
  @attrs = attrs
15
19
  @processed_attrs = @attrs
16
20
  @errors = {}
17
21
  end
18
22
 
23
+ # Processes the attributes, both validating them and processing them
24
+ # into a format suitable for Rentlinx.
25
+ #
26
+ # This method also populates the errors attribute, so it must be run
27
+ # before calling .valid? or querying for errors.
28
+ #
29
+ # Currently, phone number, state, zip, and leads URL are validated.
30
+ # They are passed into their own validator objects: {PhoneValidator},
31
+ # {StateValidator}, {ZipValidator}, and {UrlValidator}
32
+ #
33
+ # @return the processed attributes ready to submit to Rentlinx
19
34
  def process
20
35
  validators = { phoneNumber: PhoneValidator,
21
36
  state: StateValidator,
22
37
  zip: ZipValidator,
23
38
  leadsURL: UrlValidator,
24
- city: CityValidator }
39
+ city: CityValidator,
40
+ address: AddressValidator }
25
41
 
26
42
  @attrs.each do |field, val|
27
43
  next unless validators.keys.include?(field)
@@ -33,6 +49,9 @@ module Rentlinx
33
49
  @processed_attrs
34
50
  end
35
51
 
52
+ # Determines the validity of the attributes it contains.
53
+ #
54
+ # @return [Boolean] true if valid, false if not
36
55
  def valid?
37
56
  @errors.size == 0
38
57
  end
@@ -1,21 +1,33 @@
1
1
  module Rentlinx
2
+ # This is the base validator. It encapsulates all the logic shared
3
+ # between the various validators.
2
4
  class BaseValidator
3
5
  attr_reader :error
4
6
 
7
+ # Creates a new instance of the class, and validates but
8
+ # BaseValidator should never be directly instantiated.
5
9
  def initialize(val)
6
10
  @value = val
7
11
  @error = ''
8
12
  validate
9
13
  end
10
14
 
15
+ # Determines the validity of the attribute.
16
+ #
17
+ # @return true if valid, false if invalid
11
18
  def valid?
12
19
  @error == ''
13
20
  end
14
21
 
22
+ # The processed value after validation of the attribute.
23
+ #
24
+ # @return a processed value, a stripped phone number for example
15
25
  def processed_value
16
26
  @value
17
27
  end
18
28
 
29
+ private
30
+
19
31
  def value_blank?
20
32
  @value.nil? || @value == ''
21
33
  end
@@ -1,4 +1,7 @@
1
1
  module Rentlinx
2
+ # Validator for cities
3
+ #
4
+ # Ensures they are three or more characters.
2
5
  class CityValidator < BaseValidator
3
6
  private
4
7
 
@@ -1,7 +1,9 @@
1
1
  require 'phony'
2
2
 
3
3
  module Rentlinx
4
+ # Validator for phone numbers
4
5
  class PhoneValidator < BaseValidator
6
+ # Validates and normalizes the phone number with Phony
5
7
  def processed_value
6
8
  return '' if value_blank?
7
9
  return @value unless valid?
@@ -1,4 +1,7 @@
1
1
  module Rentlinx
2
+ # Validator for two letter state codes
3
+ #
4
+ # Contains a list of all the states Rentlinx permits
2
5
  class StateValidator < BaseValidator
3
6
  STATES = %w(AK AL AR AS AZ CA CO CT DC DE FL GA GU HI IA ID IL IN KS KY LA
4
7
  MA MD ME MI MN MO MP MS MT NC ND NE NH NJ NM NV NY OH OK OR PA
@@ -1,4 +1,5 @@
1
1
  module Rentlinx
2
+ # Validator for URLs
2
3
  class UrlValidator < BaseValidator
3
4
  private
4
5
 
@@ -1,4 +1,5 @@
1
1
  module Rentlinx
2
+ # Validator for US postal codes
2
3
  class ZipValidator < BaseValidator
3
4
  private
4
5
 
@@ -1,3 +1,5 @@
1
+ # This is the main rentlinx module. All Rentlinx objects
2
+ # and methods are namespaced under this module.
1
3
  module Rentlinx
2
- VERSION = '0.9.0'
4
+ VERSION = '0.9.1'
3
5
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: rentlinx
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.9.0
4
+ version: 0.9.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - AppFolio, Inc.
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2015-09-30 00:00:00.000000000 Z
11
+ date: 2015-10-02 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: httpclient
@@ -95,6 +95,7 @@ files:
95
95
  - lib/rentlinx/modules/photoable.rb
96
96
  - lib/rentlinx/modules/property_client_methods.rb
97
97
  - lib/rentlinx/modules/unit_client_methods.rb
98
+ - lib/rentlinx/validators/address_validator.rb
98
99
  - lib/rentlinx/validators/attribute_processor_service.rb
99
100
  - lib/rentlinx/validators/base_validator.rb
100
101
  - lib/rentlinx/validators/city_validator.rb
@@ -123,9 +124,8 @@ required_rubygems_version: !ruby/object:Gem::Requirement
123
124
  version: '0'
124
125
  requirements: []
125
126
  rubyforge_project:
126
- rubygems_version: 2.4.5.1
127
+ rubygems_version: 2.4.8
127
128
  signing_key:
128
129
  specification_version: 4
129
130
  summary: API Wrapper for the Rentlinx API
130
131
  test_files: []
131
- has_rdoc: