desk_api 0.1.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.
Files changed (100) hide show
  1. checksums.yaml +7 -0
  2. data/.coveralls.yml +1 -0
  3. data/.rspec +1 -0
  4. data/.travis.yml +5 -0
  5. data/.yardopts +3 -0
  6. data/Gemfile +15 -0
  7. data/Guardfile +5 -0
  8. data/LICENSE +7 -0
  9. data/README.md +185 -0
  10. data/Rakefile +15 -0
  11. data/config.rb +7 -0
  12. data/desk_api.gemspec +36 -0
  13. data/lib/desk/action/create.rb +15 -0
  14. data/lib/desk/action/delete.rb +9 -0
  15. data/lib/desk/action/embedded.rb +12 -0
  16. data/lib/desk/action/field.rb +33 -0
  17. data/lib/desk/action/link.rb +29 -0
  18. data/lib/desk/action/resource.rb +14 -0
  19. data/lib/desk/action/search.rb +15 -0
  20. data/lib/desk/action/update.rb +12 -0
  21. data/lib/desk/client.rb +67 -0
  22. data/lib/desk/configuration.rb +132 -0
  23. data/lib/desk/default.rb +67 -0
  24. data/lib/desk/error/bad_gateway.rb +10 -0
  25. data/lib/desk/error/bad_request.rb +10 -0
  26. data/lib/desk/error/client_error.rb +9 -0
  27. data/lib/desk/error/configuration_error.rb +8 -0
  28. data/lib/desk/error/conflict.rb +10 -0
  29. data/lib/desk/error/forbidden.rb +10 -0
  30. data/lib/desk/error/gateway_timeout.rb +10 -0
  31. data/lib/desk/error/internal_server_error.rb +10 -0
  32. data/lib/desk/error/method_not_allowed.rb +10 -0
  33. data/lib/desk/error/method_not_supported.rb +9 -0
  34. data/lib/desk/error/not_acceptable.rb +10 -0
  35. data/lib/desk/error/not_found.rb +10 -0
  36. data/lib/desk/error/parse_error.rb +9 -0
  37. data/lib/desk/error/parser_error.rb +9 -0
  38. data/lib/desk/error/server_error.rb +9 -0
  39. data/lib/desk/error/service_unavailable.rb +10 -0
  40. data/lib/desk/error/too_many_requests.rb +10 -0
  41. data/lib/desk/error/unauthorized.rb +10 -0
  42. data/lib/desk/error/unprocessable_entity.rb +10 -0
  43. data/lib/desk/error/unsupported_media_type.rb +10 -0
  44. data/lib/desk/error.rb +61 -0
  45. data/lib/desk/rate_limit.rb +26 -0
  46. data/lib/desk/request/retry.rb +51 -0
  47. data/lib/desk/resource/article.rb +10 -0
  48. data/lib/desk/resource/article_translation.rb +8 -0
  49. data/lib/desk/resource/attachment.rb +8 -0
  50. data/lib/desk/resource/case.rb +9 -0
  51. data/lib/desk/resource/company.rb +8 -0
  52. data/lib/desk/resource/customer.rb +9 -0
  53. data/lib/desk/resource/integration_url.rb +9 -0
  54. data/lib/desk/resource/job.rb +7 -0
  55. data/lib/desk/resource/label.rb +9 -0
  56. data/lib/desk/resource/macro.rb +9 -0
  57. data/lib/desk/resource/macro_action.rb +7 -0
  58. data/lib/desk/resource/note.rb +7 -0
  59. data/lib/desk/resource/page.rb +81 -0
  60. data/lib/desk/resource/reply.rb +8 -0
  61. data/lib/desk/resource/topic.rb +9 -0
  62. data/lib/desk/resource/topic_translation.rb +9 -0
  63. data/lib/desk/resource/user_preference.rb +7 -0
  64. data/lib/desk/resource.rb +53 -0
  65. data/lib/desk/resources.json +76 -0
  66. data/lib/desk/response/raise_error.rb +34 -0
  67. data/lib/desk/version.rb +3 -0
  68. data/lib/desk.rb +35 -0
  69. data/spec/cassettes/Desk_Client/_delete/deletes_a_resource.yml +48 -0
  70. data/spec/cassettes/Desk_Client/_get/fetches_resources.yml +55 -0
  71. data/spec/cassettes/Desk_Client/_patch/updates_a_resource.yml +62 -0
  72. data/spec/cassettes/Desk_Client/_post/creates_a_resource.yml +58 -0
  73. data/spec/cassettes/Desk_Error/_from_response/can_be_created_from_a_faraday_response.yml +54 -0
  74. data/spec/cassettes/Desk_Error/_from_response/uses_the_body_message_if_present.yml +54 -0
  75. data/spec/cassettes/Desk_Resource/_by_url/finds_resources_by_url.yml +313 -0
  76. data/spec/cassettes/Desk_Resource/_create/creates_a_new_topic.yml +58 -0
  77. data/spec/cassettes/Desk_Resource/_delete/deletes_a_resource.yml +164 -0
  78. data/spec/cassettes/Desk_Resource/_delete/throws_an_error_deleting_a_non_deletalbe_resource.yml +56 -0
  79. data/spec/cassettes/Desk_Resource/_exec_/can_be_forced_to_reload.yml +313 -0
  80. data/spec/cassettes/Desk_Resource/_exec_/loads_the_current_resource.yml +313 -0
  81. data/spec/cassettes/Desk_Resource/_method_missing/loads_the_resource_to_find_a_suitable_method.yml +313 -0
  82. data/spec/cassettes/Desk_Resource/_method_missing/raises_an_error_if_method_does_not_exist.yml +313 -0
  83. data/spec/cassettes/Desk_Resource/_search/allows_searching_on_search_enabled_resources.yml +54 -0
  84. data/spec/cassettes/Desk_Resource/_update/throws_an_error_updating_a_user.yml +56 -0
  85. data/spec/cassettes/Desk_Resource/_update/updates_a_topic.yml +118 -0
  86. data/spec/cassettes/Desk_Resource_Page/_by_id/loads_the_requested_resource.yml +54 -0
  87. data/spec/cassettes/Desk_Resource_Page/_page/keeps_the_resource_as_loaded.yml +113 -0
  88. data/spec/cassettes/Desk_Resource_Page/_page/returns_the_current_page_and_loads_if_page_not_defined.yml +313 -0
  89. data/spec/cassettes/Desk_Resource_Page/_page/sets_the_resource_to_not_loaded.yml +113 -0
  90. data/spec/desk/client_spec.rb +133 -0
  91. data/spec/desk/configuration_spec.rb +183 -0
  92. data/spec/desk/default_spec.rb +69 -0
  93. data/spec/desk/error_spec.rb +23 -0
  94. data/spec/desk/rate_limit_spec.rb +42 -0
  95. data/spec/desk/request/retry_spec.rb +46 -0
  96. data/spec/desk/resource_spec.rb +119 -0
  97. data/spec/desk/resources/page_spec.rb +64 -0
  98. data/spec/desk_spec.rb +43 -0
  99. data/spec/spec_helper.rb +39 -0
  100. metadata +347 -0
@@ -0,0 +1,67 @@
1
+ require 'desk/version'
2
+
3
+ module Desk
4
+ module Default
5
+ CONNECTION_OPTIONS = {
6
+ headers: {
7
+ accept: 'application/json',
8
+ user_agent: "desk.com Ruby Gem v#{Desk::VERSION}"
9
+ },
10
+ request: {
11
+ open_timeout: 5,
12
+ timeout: 10
13
+ }
14
+ } unless defined? Desk::Default::CONNECTION_OPTIONS
15
+
16
+ class << self
17
+ # @return [Hash]
18
+ def options
19
+ Hash[Desk::Configuration.keys.map{|key| [key, send(key)]}]
20
+ end
21
+
22
+ # @return [String]
23
+ def username
24
+ ENV['DESK_USERNAME']
25
+ end
26
+
27
+ # @return [String]
28
+ def password
29
+ ENV['DESK_PASSWORD']
30
+ end
31
+
32
+ # @return [String]
33
+ def consumer_key
34
+ ENV['DESK_CONSUMER_KEY']
35
+ end
36
+
37
+ # @return [String]
38
+ def consumer_secret
39
+ ENV['DESK_CONSUMER_SECRET']
40
+ end
41
+
42
+ # @return [String]
43
+ def token
44
+ ENV['DESK_TOKEN']
45
+ end
46
+
47
+ # @return [String]
48
+ def token_secret
49
+ ENV['DESK_TOKEN_SECRET']
50
+ end
51
+
52
+ # @return [String]
53
+ def subdomain
54
+ ENV['DESK_SUBDOMAIN']
55
+ end
56
+
57
+ # @return [String]
58
+ def endpoint
59
+ ENV['DESK_ENDPOINT']
60
+ end
61
+
62
+ def connection_options
63
+ CONNECTION_OPTIONS
64
+ end
65
+ end
66
+ end
67
+ end
@@ -0,0 +1,10 @@
1
+ require 'desk/error/server_error'
2
+
3
+ module Desk
4
+ class Error
5
+ # Raised when Desk returns the HTTP status code 502
6
+ class BadGateway < Desk::Error::ServerError
7
+ HTTP_STATUS_CODE = 502
8
+ end
9
+ end
10
+ end
@@ -0,0 +1,10 @@
1
+ require 'desk/error/client_error'
2
+
3
+ module Desk
4
+ class Error
5
+ # Raised when desk.com returns the HTTP status code 400
6
+ class BadRequest < Desk::Error::ClientError
7
+ HTTP_STATUS_CODE = 400
8
+ end
9
+ end
10
+ end
@@ -0,0 +1,9 @@
1
+ require 'desk/error'
2
+
3
+ module Desk
4
+ class Error
5
+ # Raised when desk.com returns a 4xx HTTP status code or there's an error in Faraday
6
+ class ClientError < Desk::Error
7
+ end
8
+ end
9
+ end
@@ -0,0 +1,8 @@
1
+ require 'desk/error'
2
+
3
+ module Desk
4
+ class Error
5
+ class ConfigurationError < ::ArgumentError
6
+ end
7
+ end
8
+ end
@@ -0,0 +1,10 @@
1
+ require 'desk/error/client_error'
2
+
3
+ module Desk
4
+ class Error
5
+ # Raised when desk.com returns the HTTP status code 409
6
+ class Conflict < Desk::Error::ClientError
7
+ HTTP_STATUS_CODE = 409
8
+ end
9
+ end
10
+ end
@@ -0,0 +1,10 @@
1
+ require 'desk/error/client_error'
2
+
3
+ module Desk
4
+ class Error
5
+ # Raised when desk.com returns the HTTP status code 403
6
+ class Forbidden < Desk::Error::ClientError
7
+ HTTP_STATUS_CODE = 403
8
+ end
9
+ end
10
+ end
@@ -0,0 +1,10 @@
1
+ require 'desk/error/server_error'
2
+
3
+ module Desk
4
+ class Error
5
+ # Raised when Desk returns the HTTP status code 504
6
+ class GatewayTimeout < Desk::Error::ServerError
7
+ HTTP_STATUS_CODE = 504
8
+ end
9
+ end
10
+ end
@@ -0,0 +1,10 @@
1
+ require 'desk/error/server_error'
2
+
3
+ module Desk
4
+ class Error
5
+ # Raised when Desk returns the HTTP status code 500
6
+ class InternalServerError < Desk::Error::ServerError
7
+ HTTP_STATUS_CODE = 500
8
+ end
9
+ end
10
+ end
@@ -0,0 +1,10 @@
1
+ require 'desk/error/client_error'
2
+
3
+ module Desk
4
+ class Error
5
+ # Raised when desk.com returns the HTTP status code 405
6
+ class MethodNotAllowed < Desk::Error::ClientError
7
+ HTTP_STATUS_CODE = 405
8
+ end
9
+ end
10
+ end
@@ -0,0 +1,9 @@
1
+ require 'desk/error'
2
+
3
+ module Desk
4
+ class Error
5
+ # Raised when trying to search a resource that doesn't support search
6
+ class MethodNotSupported < Desk::Error
7
+ end
8
+ end
9
+ end
@@ -0,0 +1,10 @@
1
+ require 'desk/error/client_error'
2
+
3
+ module Desk
4
+ class Error
5
+ # Raised when desk.com returns the HTTP status code 406
6
+ class NotAcceptable < Desk::Error::ClientError
7
+ HTTP_STATUS_CODE = 406
8
+ end
9
+ end
10
+ end
@@ -0,0 +1,10 @@
1
+ require 'desk/error/client_error'
2
+
3
+ module Desk
4
+ class Error
5
+ # Raised when desk.com returns the HTTP status code 404
6
+ class NotFound < Desk::Error::ClientError
7
+ HTTP_STATUS_CODE = 404
8
+ end
9
+ end
10
+ end
@@ -0,0 +1,9 @@
1
+ require 'desk/error'
2
+
3
+ module Desk
4
+ class Error
5
+ # Raised when JSON parsing fails
6
+ class ParserError < Desk::Error
7
+ end
8
+ end
9
+ end
@@ -0,0 +1,9 @@
1
+ require 'desk/error'
2
+
3
+ module Desk
4
+ class Error
5
+ # Raised when JSON parsing fails
6
+ class ParserError < Desk::Error
7
+ end
8
+ end
9
+ end
@@ -0,0 +1,9 @@
1
+ require 'desk/error'
2
+
3
+ module Desk
4
+ class Error
5
+ # Raised when Desk returns a 5xx HTTP status code
6
+ class ServerError < Desk::Error
7
+ end
8
+ end
9
+ end
@@ -0,0 +1,10 @@
1
+ require 'desk/error/server_error'
2
+
3
+ module Desk
4
+ class Error
5
+ # Raised when Desk returns the HTTP status code 503
6
+ class ServiceUnavailable < Desk::Error::ServerError
7
+ HTTP_STATUS_CODE = 503
8
+ end
9
+ end
10
+ end
@@ -0,0 +1,10 @@
1
+ require 'desk/error/client_error'
2
+
3
+ module Desk
4
+ class Error
5
+ # Raised when desk.com returns the HTTP status code 429
6
+ class TooManyRequests < Desk::Error::ClientError
7
+ HTTP_STATUS_CODE = 429
8
+ end
9
+ end
10
+ end
@@ -0,0 +1,10 @@
1
+ require 'desk/error/client_error'
2
+
3
+ module Desk
4
+ class Error
5
+ # Raised when desk.com returns the HTTP status code 401
6
+ class Unauthorized < Desk::Error::ClientError
7
+ HTTP_STATUS_CODE = 401
8
+ end
9
+ end
10
+ end
@@ -0,0 +1,10 @@
1
+ require 'desk/error/client_error'
2
+
3
+ module Desk
4
+ class Error
5
+ # Raised when desk.com returns the HTTP status code 422
6
+ class UnprocessableEntity < Desk::Error::ClientError
7
+ HTTP_STATUS_CODE = 422
8
+ end
9
+ end
10
+ end
@@ -0,0 +1,10 @@
1
+ require 'desk/error/client_error'
2
+
3
+ module Desk
4
+ class Error
5
+ # Raised when desk.com returns the HTTP status code 415
6
+ class UnsupportedMediaType < Desk::Error::ClientError
7
+ HTTP_STATUS_CODE = 415
8
+ end
9
+ end
10
+ end
data/lib/desk/error.rb ADDED
@@ -0,0 +1,61 @@
1
+ require 'desk/rate_limit'
2
+
3
+ module Desk
4
+ # Custom error class for rescuing from all desk.com errors
5
+ class Error < StandardError
6
+ attr_reader :rate_limit
7
+
8
+ # Initializes a new Error object
9
+ #
10
+ # @param exception [Exception, String]
11
+ # @param response_headers [Hash]
12
+ # @param code [Integer]
13
+ # @return [Desk::Error]
14
+ def initialize(exception=$!, response_headers={}, code = nil)
15
+ @rate_limit = Desk::RateLimit.new(response_headers)
16
+ @wrapped_exception = exception
17
+ @code = code
18
+ exception.respond_to?(:backtrace) ? super(exception.message) : super(exception.to_s)
19
+ end
20
+
21
+ def backtrace
22
+ @wrapped_exception.respond_to?(:backtrace) ? @wrapped_exception.backtrace : super
23
+ end
24
+
25
+ class << self
26
+ # Create a new error from an HTTP response
27
+ #
28
+ # @param response [Hash]
29
+ # @return [Desk::Error]
30
+ def from_response(response = {})
31
+ error, code = parse_error(response[:body]), response[:status]
32
+ new(error, response[:response_headers], code)
33
+ end
34
+
35
+ # @return [Hash]
36
+ def errors
37
+ @errors ||= descendants.each_with_object({}) do |klass, hash|
38
+ hash[klass::HTTP_STATUS_CODE] = klass
39
+ end
40
+ end
41
+
42
+ # @return [Array]
43
+ def descendants
44
+ @descendants ||= []
45
+ end
46
+
47
+ # @return [Array]
48
+ def inherited(descendant)
49
+ descendants << descendant
50
+ end
51
+
52
+ private
53
+
54
+ def parse_error(body)
55
+ if body['message']
56
+ body['message']
57
+ end
58
+ end
59
+ end
60
+ end
61
+ end
@@ -0,0 +1,26 @@
1
+ module Desk
2
+ class RateLimit
3
+ def initialize(attrs = {})
4
+ @attrs = attrs
5
+ end
6
+
7
+ # @return [Integer]
8
+ def limit
9
+ limit = @attrs['x-rate-limit-limit']
10
+ limit.to_i if limit
11
+ end
12
+
13
+ # @return [Integer]
14
+ def remaining
15
+ remaining = @attrs['x-rate-limit-remaining']
16
+ remaining.to_i if remaining
17
+ end
18
+
19
+ # @return [Integer]
20
+ def reset_in
21
+ reset_in = @attrs['x-rate-limit-reset']
22
+ reset_in.to_i if reset_in
23
+ end
24
+ alias retry_after reset_in
25
+ end
26
+ end
@@ -0,0 +1,51 @@
1
+ module Desk
2
+ module Request
3
+ class Retry < Faraday::Request::Retry
4
+ def initialize(app, options = {})
5
+ @max = options[:max] || 3
6
+ @interval = options[:interval] || 10
7
+ super(app)
8
+ end
9
+
10
+ def call(env)
11
+ retries = @retries
12
+ interval = @interval
13
+
14
+ begin
15
+ @app.call(env)
16
+ rescue Desk::Error::TooManyRequests => e
17
+ if retries > 0 and e.rate_limit.reset_in
18
+ retries = 0
19
+ sleep e.rate_limit.reset_in
20
+ retry
21
+ end
22
+ raise
23
+ rescue exception_matcher
24
+ if retries > 0
25
+ retries -= 1
26
+ sleep @interval
27
+ retry
28
+ end
29
+ raise
30
+ end
31
+ end
32
+
33
+ def exception_matcher
34
+ exceptions = [Errno::ETIMEDOUT, 'Timeout::Error', Faraday::Error::TimeoutError]
35
+ matcher = Module.new
36
+ (class << matcher; self; end).class_eval do
37
+ define_method(:===) do |error|
38
+ exceptions.any? do |ex|
39
+ if ex.is_a? Module then error.is_a? ex
40
+ else error.class.to_s == ex.to_s
41
+ end
42
+ end
43
+ end
44
+ end
45
+ matcher
46
+ end
47
+ end
48
+
49
+ Faraday.register_middleware :request, retry: lambda { Retry }
50
+ end
51
+ end
@@ -0,0 +1,10 @@
1
+ module Desk
2
+ class Resource
3
+ class Article < Desk::Resource
4
+ include Desk::Action::Create
5
+ include Desk::Action::Update
6
+ include Desk::Action::Delete
7
+ include Desk::Action::Search
8
+ end
9
+ end
10
+ end
@@ -0,0 +1,8 @@
1
+ module Desk
2
+ class Resource
3
+ class ArticleTranslation < Desk::Resource
4
+ include Desk::Action::Create
5
+ include Desk::Action::Update
6
+ end
7
+ end
8
+ end
@@ -0,0 +1,8 @@
1
+ module Desk
2
+ class Resource
3
+ class Attachment < Desk::Resource
4
+ include Desk::Action::Create
5
+ include Desk::Action::Delete
6
+ end
7
+ end
8
+ end
@@ -0,0 +1,9 @@
1
+ module Desk
2
+ class Resource
3
+ class Case < Desk::Resource
4
+ include Desk::Action::Create
5
+ include Desk::Action::Update
6
+ include Desk::Action::Search
7
+ end
8
+ end
9
+ end
@@ -0,0 +1,8 @@
1
+ module Desk
2
+ class Resource
3
+ class Company < Desk::Resource
4
+ include Desk::Action::Create
5
+ include Desk::Action::Update
6
+ end
7
+ end
8
+ end
@@ -0,0 +1,9 @@
1
+ module Desk
2
+ class Resource
3
+ class Customer < Desk::Resource
4
+ include Desk::Action::Create
5
+ include Desk::Action::Update
6
+ include Desk::Action::Search
7
+ end
8
+ end
9
+ end
@@ -0,0 +1,9 @@
1
+ module Desk
2
+ class Resource
3
+ class IntegrationUrl < Desk::Resource
4
+ include Desk::Action::Create
5
+ include Desk::Action::Update
6
+ include Desk::Action::Delete
7
+ end
8
+ end
9
+ end
@@ -0,0 +1,7 @@
1
+ module Desk
2
+ class Resource
3
+ class Job < Desk::Resource
4
+ include Desk::Action::Create
5
+ end
6
+ end
7
+ end
@@ -0,0 +1,9 @@
1
+ module Desk
2
+ class Resource
3
+ class Article < Desk::Resource
4
+ include Desk::Action::Create
5
+ include Desk::Action::Update
6
+ include Desk::Action::Delete
7
+ end
8
+ end
9
+ end
@@ -0,0 +1,9 @@
1
+ module Desk
2
+ class Resource
3
+ class Macro < Desk::Resource
4
+ include Desk::Action::Create
5
+ include Desk::Action::Update
6
+ include Desk::Action::Delete
7
+ end
8
+ end
9
+ end
@@ -0,0 +1,7 @@
1
+ module Desk
2
+ class Resource
3
+ class MacroAction < Desk::Resource
4
+ include Desk::Action::Update
5
+ end
6
+ end
7
+ end
@@ -0,0 +1,7 @@
1
+ module Desk
2
+ class Resource
3
+ class Note < Desk::Resource
4
+ include Desk::Action::Create
5
+ end
6
+ end
7
+ end
@@ -0,0 +1,81 @@
1
+ module Desk
2
+ class Resource
3
+ class Page < Desk::Resource
4
+ include Enumerable
5
+ include Desk::Action::Embedded
6
+
7
+ [
8
+ :all?, :any?,
9
+ :collect, :each, :entries, :find, :find_all,
10
+ :find_index, :first, :first, :group_by, :last,
11
+ :map, :map!, :none?, :one?, :partition, :reduce,
12
+ :reject, :select, :sort, :sort_by, :taken, :zip
13
+ ].each do |method|
14
+ define_method(method) do |*args, &block|
15
+ exec!.records.send(method, *args, &block)
16
+ end
17
+ end
18
+
19
+ def search(params)
20
+ raise Desk::Error::MethodNotSupported unless base_class.respond_to?(:search)
21
+ url = Addressable::URI.parse(clean_base_url + '/search')
22
+ url.query_values = params
23
+ base_class.search(client, url.to_s).exec!
24
+ end
25
+
26
+ def create(params)
27
+ raise Desk::Error::MethodNotSupported unless base_class.respond_to?(:create)
28
+ base_class.create(client, clean_base_url, params)
29
+ end
30
+
31
+ [:page, :per_page].each do |method|
32
+ define_method(method) do |value = nil|
33
+ if not value
34
+ self.exec! if self.query_params(method.to_s) == nil
35
+ return self.query_params(method.to_s).to_i
36
+ end
37
+ self.query_params = Hash[method.to_s, value.to_s]
38
+ self
39
+ end
40
+ end
41
+
42
+ def by_id(id)
43
+ by_url("#{clean_base_url}/#{id}")
44
+ end
45
+
46
+ protected
47
+
48
+ attr_reader :records
49
+
50
+ def setup(definition)
51
+ setup_embedded(definition._embedded['entries']) if definition._embedded?
52
+ super(definition)
53
+ end
54
+
55
+ def query_params(param)
56
+ params = Addressable::URI.parse(@_links.self.href).query_values || {}
57
+ params.include?(param) ? params[param] : nil
58
+ end
59
+
60
+ def query_params=(params = {})
61
+ return @_links.self.href if params.empty?
62
+
63
+ uri = Addressable::URI.parse(@_links.self.href)
64
+ params = (uri.query_values || {}).merge(params)
65
+
66
+ @loaded = false unless params == uri.query_values
67
+
68
+ uri.query_values = params
69
+ @_links.self.href = uri.to_s
70
+ end
71
+
72
+ def clean_base_url
73
+ Addressable::URI.parse(@_links.self.href).path.gsub(/\/search$/, '')
74
+ end
75
+
76
+ def base_class
77
+ resource(clean_base_url[/\w+$/].singularize)
78
+ end
79
+ end
80
+ end
81
+ end
@@ -0,0 +1,8 @@
1
+ module Desk
2
+ class Resource
3
+ class Reply < Desk::Resource
4
+ include Desk::Action::Create
5
+ include Desk::Action::Update
6
+ end
7
+ end
8
+ end
@@ -0,0 +1,9 @@
1
+ module Desk
2
+ class Resource
3
+ class Topic < Desk::Resource
4
+ include Desk::Action::Create
5
+ include Desk::Action::Update
6
+ include Desk::Action::Delete
7
+ end
8
+ end
9
+ end
@@ -0,0 +1,9 @@
1
+ module Desk
2
+ class Resource
3
+ class TopicTranslation < Desk::Resource
4
+ include Desk::Action::Create
5
+ include Desk::Action::Update
6
+ include Desk::Action::Delete
7
+ end
8
+ end
9
+ end
@@ -0,0 +1,7 @@
1
+ module Desk
2
+ class Resource
3
+ class UserPreference < Desk::Resource
4
+ include Desk::Action::Update
5
+ end
6
+ end
7
+ end