easy-resources 0.8.2 → 0.10.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (49) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +76 -0
  3. data/lib/easy/resource.rb +12 -9
  4. data/lib/easy/resources/redmine/custom_field.rb +36 -0
  5. data/lib/easy/resources/redmine/easy_attendance.rb +0 -1
  6. data/lib/easy/resources/redmine/easy_contact.rb +0 -1
  7. data/lib/easy/resources/redmine/easy_crm_case.rb +0 -1
  8. data/lib/easy/resources/redmine/easy_server.rb +1 -1
  9. data/lib/easy/resources/redmine/easy_web_application.rb +19 -2
  10. data/lib/easy/resources/redmine/easy_web_application_activity.rb +0 -1
  11. data/lib/easy/resources/redmine/easy_web_hook.rb +0 -1
  12. data/lib/easy/resources/redmine/errors.rb +7 -2
  13. data/lib/easy/resources/redmine/issue.rb +0 -1
  14. data/lib/easy/resources/redmine/project.rb +0 -1
  15. data/lib/easy/resources/redmine/redmine_base.rb +3 -3
  16. data/lib/easy/resources/redmine/time_entry.rb +0 -1
  17. data/lib/easy/resources/redmine/user.rb +0 -1
  18. data/lib/easy/resources/spec_helper.rb +2 -2
  19. data/lib/easy/resources/version.rb +3 -1
  20. data/lib/easy/resources.rb +5 -0
  21. data/spec/easy_resources_spec.rb +0 -3
  22. data/spec/fixtures/files/custom_field/bool.xml +4 -0
  23. data/spec/fixtures/files/custom_field/date.xml +4 -0
  24. data/spec/fixtures/files/custom_field/datetime.xml +5 -0
  25. data/spec/fixtures/files/custom_field/float.xml +4 -0
  26. data/spec/fixtures/files/custom_field/int.xml +4 -0
  27. data/spec/fixtures/files/custom_field/string.xml +4 -0
  28. data/spec/fixtures/files/easy_web_application/show.xml +8 -0
  29. data/spec/fixtures/files/easy_web_hook/index.xml +26 -0
  30. data/spec/fixtures/files/easy_web_hook/show.xml +11 -0
  31. data/spec/models/easy-resources/redmine/custom_field_spec.rb +31 -0
  32. data/spec/models/easy-resources/redmine/easy_attendance_spec.rb +0 -1
  33. data/spec/models/easy-resources/redmine/easy_contact_spec.rb +0 -1
  34. data/spec/models/easy-resources/redmine/easy_crm_case_spec.rb +0 -2
  35. data/spec/models/easy-resources/redmine/easy_server_spec.rb +0 -1
  36. data/spec/models/easy-resources/redmine/easy_web_application_activity_spec.rb +0 -1
  37. data/spec/models/easy-resources/redmine/easy_web_application_spec.rb +13 -2
  38. data/spec/models/easy-resources/redmine/easy_web_hook_spec.rb +9 -0
  39. data/spec/models/easy-resources/redmine/errors_spec.rb +0 -1
  40. data/spec/models/easy-resources/redmine/issue_spec.rb +0 -2
  41. data/spec/models/easy-resources/redmine/project_spec.rb +0 -2
  42. data/spec/models/easy-resources/redmine/redmine_base_spec.rb +0 -2
  43. data/spec/models/easy-resources/redmine/time_entry_spec.rb +0 -1
  44. data/spec/models/easy-resources/redmine/user_spec.rb +0 -2
  45. data/spec/models/easy-resources/resource_spec.rb +2 -2
  46. data/spec/spec_helper.rb +5 -4
  47. data/spec/support/active_resource.rb +1 -1
  48. data/spec/support/redmine_active_resource.rb +2 -2
  49. metadata +111 -58
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: baa165cfc453f4d26f80848a0e3e7e62b53c55510865b0354d5bc610f5cd3651
4
- data.tar.gz: f7dea1efcddaef350f4180d2752635928b55cc219b3bb653f51295b932841e4e
3
+ metadata.gz: 29cce503c0d0908bb6a5bd6816fda1add2f38ae73e9b69eb4fb1f81e0106c3d4
4
+ data.tar.gz: d5e6499693d14816b6d986fb7c892b9cec455d4d22216e5cac9d47d8b9211fb9
5
5
  SHA512:
6
- metadata.gz: d74958dc95394cca13daed7e5d0e289d15c0d4f62dd766c651c5ee3ab4c66252eda81668f760789bdfe2a5ada66b1575d4d32aa7c7ef68c69b31420ec7e68061
7
- data.tar.gz: '07800fff4965abf4b05f312649f9c8d236d5dcc210d6a966435a004e8b09b54b0feb61fc6c3cce9d2f8a8113ae6f1619b768f641251f114717b628f803742f61'
6
+ metadata.gz: 54620a9d039d0932dd32be642445592340f0d7ad1b3c943f909a76b84f133ea29ed78faaf18697d9f9e9d17cc50569a504310ee9fb5ed68b2c791f63a8721f82
7
+ data.tar.gz: f472afbf20f03bf5828040e0283df010bb1f86540fc6fd2231abcdfbd96af4e0a0eb9726cd40992379c9c478fe0e17a5a2a04d7e24b793a4136e7de655686c3a
data/CHANGELOG.md ADDED
@@ -0,0 +1,76 @@
1
+ # Changelog
2
+ All notable changes to this project will be documented in this file.
3
+
4
+ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
5
+ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
6
+
7
+ ## [Unreleased]
8
+ ## [0.10.1] - 2021-09-03
9
+ ### Added
10
+ - rexml gem as a dependency (because of XML requests)
11
+ ### Changed
12
+ - .gitlab-ci.yml with Docker and ruby matrix support
13
+
14
+ ## [0.10.0] - 2021-09-01
15
+ ### Added
16
+ - support ruby3.0
17
+ ### Removed
18
+ - support ruby2.5
19
+
20
+ ## [0.9.1] - 2021-08-24
21
+ ### Fixed
22
+ - adjusted EWA schema
23
+
24
+ ## [0.9.0] - 2021-06-08
25
+ ### Added
26
+ - CustomField resource
27
+ - rubocop linter
28
+ - improve gemspec metadata
29
+ ### Changed
30
+ - dummy upgrade to rails 6
31
+ - update dev dependencies
32
+
33
+ ## [0.8.2] - 2021-03-05
34
+ ### Added
35
+ - ruby 3 compatibility
36
+
37
+ ## [0.8.1] - 2020-06-08
38
+ ### Fixed
39
+ - Retrieve (Easy)Redmine total entities from response if headers missing
40
+ - Validation error messages parser from XML
41
+
42
+ ## [0.8.0] - 2020-04-28
43
+ ### Added
44
+ - TimeEntry
45
+ - EasyAttendance
46
+ ## [0.7.5] - 2020-03-06
47
+ ### Added
48
+ - EasyServer `status` alias for `server_status`
49
+ ## [0.7.5] - 2020-01-17
50
+ ### Added
51
+ - aasm_event into EasyWebApplication scheme
52
+ - notes into EasyWebApplication scheme
53
+ ## [0.7.4] - 2019-09-02
54
+ ### Added
55
+ - Easy Web Application add belongs_to Issue
56
+ ## [0.7.2] - 2019-08-29
57
+ ### Added
58
+ - Easy Web Hook model
59
+ ## [0.7.1] - 2019-07-11
60
+ ### Added
61
+ - configuration from Oauth2 token
62
+ ### Fixed
63
+ - api_key is changed to class_attribute
64
+ ## [0.6.3] - 2019-07-08
65
+ ### Fixed
66
+ - cached headers
67
+ ## [0.6.2] - 2019-05-14
68
+ ### Added
69
+ - alias url in server resource
70
+ ## [0.6.1] - 2019-04-03
71
+ ### Added
72
+ - this file
73
+ - User resource in Redmine
74
+ - 100% code coverage :)
75
+ ### Changed
76
+ - README
data/lib/easy/resource.rb CHANGED
@@ -2,26 +2,29 @@ module Easy
2
2
  class Resource < ActiveResource::Base
3
3
 
4
4
  def self.configure(conf)
5
- if conf.is_a?(::Hash)
5
+ case conf
6
+ when ::Hash
6
7
  if conf[:url].present? && conf[:token].present?
7
8
  configure_bearer(conf[:url], conf[:token])
8
9
  elsif conf[:url].present?
9
10
  self.site = conf[:url]
10
11
  end
11
- elsif conf.is_a?(::OAuth2::AccessToken)
12
+ when ::OAuth2::AccessToken
12
13
  configure_bearer(conf.client.site, conf.token)
14
+ else
15
+ # do nothing, unknown configuration
13
16
  end
14
17
  end
15
18
 
16
19
  def self.configure_bearer(url, token)
17
- self.site = url
18
- self.connection.auth_type = :bearer
19
- self.connection.bearer_token = token
20
+ self.site = url
21
+ connection.auth_type = :bearer
22
+ connection.bearer_token = token
20
23
  end
21
24
 
22
25
  def becomes(entity_class)
23
- model = entity_class.new
24
- model.attributes = self.attributes
26
+ model = entity_class.new
27
+ model.attributes = attributes
25
28
  model
26
29
  end
27
30
 
@@ -37,13 +40,13 @@ module Easy
37
40
  update_columns(attribute.to_sym => value)
38
41
  end
39
42
 
40
- def update_columns(**attributes)
43
+ def update_columns(attributes)
41
44
  patch(nil, {}, encode_attributes(attributes))
42
45
  end
43
46
 
44
47
  protected
45
48
 
46
- def encode_attributes(**attributes)
49
+ def encode_attributes(attributes)
47
50
  case self.class.format.extension
48
51
  when "json"
49
52
  attributes.to_json(include_root_in_json ? { root: self.class.element_name } : {})
@@ -0,0 +1,36 @@
1
+ module Easy
2
+ module Resources
3
+ module Redmine
4
+ class CustomField < RedmineBase
5
+ self.element_name = 'custom_field'
6
+
7
+ self.schema = {
8
+ id: :integer,
9
+ name: :string,
10
+ internal_name: :string,
11
+ value: :string,
12
+ field_format: :string,
13
+ }
14
+
15
+ # @return formatted value based on **field_format**
16
+ def cast_value
17
+ case field_format
18
+ when "bool"
19
+ value.to_s =~ /1|true/i ? true : false
20
+ when "float", "amount"
21
+ value.to_f
22
+ when "int"
23
+ value.to_i
24
+ when "date"
25
+ Date.parse value
26
+ when "datetime"
27
+ DateTime.parse value
28
+ else
29
+ value
30
+ end
31
+ end
32
+
33
+ end
34
+ end
35
+ end
36
+ end
@@ -2,7 +2,6 @@ module Easy
2
2
  module Resources
3
3
  module Redmine
4
4
  class EasyAttendance < RedmineBase
5
-
6
5
  self.element_name = 'easy_attendance'
7
6
 
8
7
  belongs_to :user, class_name: 'Easy::Resources::Redmine::User'
@@ -2,7 +2,6 @@ module Easy
2
2
  module Resources
3
3
  module Redmine
4
4
  class EasyContact < RedmineBase
5
-
6
5
  self.element_name = 'easy_contact'
7
6
 
8
7
  def name
@@ -2,7 +2,6 @@ module Easy
2
2
  module Resources
3
3
  module Redmine
4
4
  class EasyCrmCase < RedmineBase
5
-
6
5
  self.element_name = 'easy_crm_case'
7
6
 
8
7
  belongs_to :project, class_name: 'Easy::Resources::Redmine::Project'
@@ -2,7 +2,6 @@ module Easy
2
2
  module Resources
3
3
  module Redmine
4
4
  class EasyServer < RedmineBase
5
-
6
5
  self.element_name = 'easy_server'
7
6
 
8
7
  has_many :easy_web_applications, class_name: 'Easy::Resources::Redmine::EasyWebApplication'
@@ -12,6 +11,7 @@ module Easy
12
11
  server_type: :string,
13
12
  server_status: :string
14
13
  }
14
+
15
15
  # Alias for +host_name+ attribute
16
16
  # @return [String]
17
17
  def url
@@ -2,18 +2,22 @@ module Easy
2
2
  module Resources
3
3
  module Redmine
4
4
  class EasyWebApplication < RedmineBase
5
-
6
5
  self.element_name = 'easy_web_application'
7
6
 
8
7
  self.schema = {
9
8
  url: :string,
10
9
  git_repository: :string,
11
10
  git_branch: :string,
11
+ db_url: :string,
12
+ files_url: :string,
12
13
  issue_id: :integer,
13
14
  easy_crm_case_id: :integer,
14
15
  easy_contact_id: :integer,
15
16
  aasm_event: :string,
16
- notes: :string
17
+ notes: :string,
18
+ expire_at: :date,
19
+ custom_repository: :boolean,
20
+ custom_domain: :boolean,
17
21
  }
18
22
 
19
23
  belongs_to :easy_contact, class_name: 'Easy::Resources::Redmine::EasyContact'
@@ -21,6 +25,7 @@ module Easy
21
25
  belongs_to :easy_server, class_name: 'Easy::Resources::Redmine::EasyServer'
22
26
  belongs_to :issue, class_name: 'Easy::Resources::Redmine::Issue'
23
27
 
28
+ has_many :custom_fields, class_name: 'Easy::Resources::Redmine::CustomField'
24
29
  has_many :easy_web_application_activities, class_name: 'Easy::Resources::Redmine::EasyWebApplicationActivity'
25
30
  has_one :easy_web_application_activity, class_name: 'Easy::Resources::Redmine::EasyWebApplicationActivity'
26
31
 
@@ -28,6 +33,18 @@ module Easy
28
33
  url
29
34
  end
30
35
 
36
+ # @!group ESko specific custom_fields
37
+
38
+ # @return [Boolean,nil]
39
+ def application_moves_on_request?
40
+ custom_fields.find { |cf| cf.internal_name == "application_move_on_request" }&.cast_value
41
+ end
42
+
43
+ # @return [Boolean,nil]
44
+ def application_updates_on_request?
45
+ custom_fields.find { |cf| cf.internal_name == "application_updates_on_request" }&.cast_value
46
+ end
47
+
31
48
  end
32
49
  end
33
50
  end
@@ -2,7 +2,6 @@ module Easy
2
2
  module Resources
3
3
  module Redmine
4
4
  class EasyWebApplicationActivity < RedmineBase
5
-
6
5
  self.element_name = 'easy_web_application_activity'
7
6
 
8
7
  belongs_to :easy_web_application, class_name: 'Easy::Resources::Redmine::EasyWebApplication'
@@ -2,7 +2,6 @@ module Easy
2
2
  module Resources
3
3
  module Redmine
4
4
  class EasyWebHook < RedmineBase
5
-
6
5
  self.element_name = 'easy_web_hook'
7
6
 
8
7
  end
@@ -6,10 +6,15 @@ module Easy
6
6
  # Redmine in XML responses specify type="array" on Errors
7
7
  # It cause that `Hash.from_xml` already parsed errors as a Array
8
8
  def from_xml(xml, save_cache = false)
9
- array = Array.wrap(Hash.from_xml(xml)["errors"]) rescue []
9
+ array = begin
10
+ Array.wrap(Hash.from_xml(xml)["errors"])
11
+ rescue StandardError
12
+ []
13
+ end
10
14
  from_array array, save_cache
11
15
  end
16
+
12
17
  end
13
18
  end
14
19
  end
15
- end
20
+ end
@@ -2,7 +2,6 @@ module Easy
2
2
  module Resources
3
3
  module Redmine
4
4
  class Issue < RedmineBase
5
-
6
5
  self.element_name = 'issue'
7
6
 
8
7
  belongs_to :project, class_name: 'Easy::Resources::Redmine::Project'
@@ -2,7 +2,6 @@ module Easy
2
2
  module Resources
3
3
  module Redmine
4
4
  class Project < RedmineBase
5
-
6
5
  self.element_name = 'project'
7
6
 
8
7
  end
@@ -2,10 +2,9 @@ module Easy
2
2
  module Resources
3
3
  module Redmine
4
4
  class RedmineBase < ::Easy::Resource
5
-
6
5
  self.include_root_in_json = true
7
6
  self.format = :xml
8
- self.add_response_method :http_response
7
+ add_response_method :http_response
9
8
 
10
9
  class_attribute :api_key
11
10
 
@@ -29,7 +28,7 @@ module Easy
29
28
  # Parse value of TOTAL amount of entities from headers or response
30
29
  # @return [Integer]
31
30
  def retrieve_total(response)
32
- (response['Total'] || response.body[/total_count[:="]+(\d+)/] && $1).to_i
31
+ (response['Total'] || response.body[/total_count[:="]+(\d+)/] && Regexp.last_match(1)).to_i
33
32
  end
34
33
 
35
34
  def get_all(**params, &block)
@@ -56,6 +55,7 @@ module Easy
56
55
  def errors
57
56
  @errors ||= Errors.new(self)
58
57
  end
58
+
59
59
  end
60
60
  end
61
61
  end
@@ -2,7 +2,6 @@ module Easy
2
2
  module Resources
3
3
  module Redmine
4
4
  class TimeEntry < RedmineBase
5
-
6
5
  self.element_name = 'time_entry'
7
6
 
8
7
  belongs_to :project, class_name: 'Easy::Resources::Redmine::Project'
@@ -2,7 +2,6 @@ module Easy
2
2
  module Resources
3
3
  module Redmine
4
4
  class User < RedmineBase
5
-
6
5
  self.element_name = 'user'
7
6
 
8
7
  def name
@@ -1,2 +1,2 @@
1
- x = File.expand_path('../../../../', __FILE__)
2
- Dir["#{x}/spec/support/**/*.rb"].sort.each { |f| require f }
1
+ gem_dir = File.expand_path('../../..', __dir__)
2
+ Dir["#{gem_dir}/spec/support/**/*.rb"].sort.each { |f| require f }
@@ -1,5 +1,7 @@
1
1
  module Easy
2
2
  module Resources
3
- VERSION = '0.8.2'
3
+
4
+ VERSION = '0.10.1'
5
+
4
6
  end
5
7
  end
@@ -2,8 +2,11 @@ require "activeresource"
2
2
  require "activeresource-response"
3
3
 
4
4
  require "easy/resources/railtie"
5
+ require "rexml"
6
+ require "rexml/document"
5
7
 
6
8
  module Easy
9
+
7
10
  autoload :Resource, "easy/resource"
8
11
 
9
12
  module Resources
@@ -11,6 +14,7 @@ module Easy
11
14
 
12
15
  autoload :Errors, "easy/resources/redmine/errors"
13
16
 
17
+ autoload :CustomField, "easy/resources/redmine/custom_field"
14
18
  autoload :RedmineBase, "easy/resources/redmine/redmine_base"
15
19
  autoload :EasyAttendance, "easy/resources/redmine/easy_attendance"
16
20
  autoload :EasyContact, "easy/resources/redmine/easy_contact"
@@ -26,4 +30,5 @@ module Easy
26
30
 
27
31
  end
28
32
  end
33
+
29
34
  end
@@ -6,7 +6,6 @@ RSpec.describe Easy::Resources do
6
6
  end
7
7
 
8
8
  describe '.configure' do
9
-
10
9
  context "Easy::Resources::Redmine::RedmineBase" do
11
10
  it "Easy::Resources::Redmine::RedmineBase" do
12
11
  expect(Easy::Resources::Redmine::RedmineBase).to receive(:api_key=).with("xx1")
@@ -14,7 +13,5 @@ RSpec.describe Easy::Resources do
14
13
  Easy::Resources::Redmine::RedmineBase.configure api_key: "xx1", url: "https://test.dummy"
15
14
  end
16
15
  end
17
-
18
16
  end
19
-
20
17
  end
@@ -0,0 +1,4 @@
1
+ <?xml version="1.0" encoding="UTF-8"?>
2
+ <custom_field id="1" name="Move on-request" internal_name="application_move_on_request" field_format="bool">
3
+ <value>1</value>
4
+ </custom_field>
@@ -0,0 +1,4 @@
1
+ <?xml version="1.0" encoding="UTF-8"?>
2
+ <custom_field id="1" name="Next action" field_format="date">
3
+ <value>2020-06-24</value>
4
+ </custom_field>
@@ -0,0 +1,5 @@
1
+ <?xml version="1.0" encoding="UTF-8"?>
2
+ <custom_field id="1" name="Next action" field_format="datetime">
3
+ <value>2020-06-24 22:00:00</value>
4
+ <local_datetime>2020-06-25T00:00:00+02:00</local_datetime>
5
+ </custom_field>
@@ -0,0 +1,4 @@
1
+ <?xml version="1.0" encoding="UTF-8"?>
2
+ <custom_field id="1" name="Next action" field_format="float">
3
+ <value>24</value>
4
+ </custom_field>
@@ -0,0 +1,4 @@
1
+ <?xml version="1.0" encoding="UTF-8"?>
2
+ <custom_field id="1" name="Next action" field_format="int">
3
+ <value></value>
4
+ </custom_field>
@@ -0,0 +1,4 @@
1
+ <?xml version="1.0" encoding="UTF-8"?>
2
+ <custom_field id="1" name="Next action" field_format="text">
3
+ <value>word</value>
4
+ </custom_field>
@@ -11,6 +11,14 @@
11
11
  <author id="14" name="Anonymní"/>
12
12
  <internal_user_limit>0</internal_user_limit>
13
13
  <git_repository type="string">git@git.easy.cz:package.git</git_repository>
14
+ <custom_fields type="array">
15
+ <custom_field id="695" name="Move on-request" internal_name="application_move_on_request" field_format="bool">
16
+ <value>1</value>
17
+ </custom_field>
18
+ <custom_field id="463" name="Updates on-request" internal_name="application_updates_on_request" field_format="bool">
19
+ <value>0</value>
20
+ </custom_field>
21
+ </custom_fields>
14
22
  <created_at>2018-03-22T09:10:47Z</created_at>
15
23
  <updated_at>2018-05-24T10:55:28Z</updated_at>
16
24
  </easy_web_application>
@@ -0,0 +1,26 @@
1
+ <?xml version="1.0" encoding="UTF-8"?>
2
+ <easy_web_hooks total_count="12" offset="0" limit="25" type="array">
3
+ <easy_web_hook>
4
+ <id>1</id>
5
+ <url>https://hooks.integromat.com/super-secret-hash</url>
6
+ <status>inactive</status>
7
+ <entity_type>Issue</entity_type>
8
+ <action>create</action>
9
+ <author id="1" name="Manager"/>
10
+ <api_includes>[]</api_includes>
11
+ <created_at>2017-08-18T11:56:53Z</created_at>
12
+ <updated_at>2019-08-29T07:44:16Z</updated_at>
13
+ </easy_web_hook>
14
+ <easy_web_hook>
15
+ <id>3</id>
16
+ <url>https://hooks.zapier.com/hooks/catch/hookID/hookSecret/</url>
17
+ <status>inactive</status>
18
+ <entity_type>Project</entity_type>
19
+ <action>destroy</action>
20
+ <author id="5" name="Admin"/>
21
+ <project id="7" name="Reporting"/>
22
+ <api_includes>[issue_categories]</api_includes>
23
+ <created_at>2019-06-19T11:41:22Z</created_at>
24
+ <updated_at>2019-06-19T11:41:22Z</updated_at>
25
+ </easy_web_hook>
26
+ </easy_web_hooks>
@@ -0,0 +1,11 @@
1
+ <easy_web_hook>
2
+ <id>1</id>
3
+ <url>https://hooks.integromat.com/super-secret-hash</url>
4
+ <status>inactive</status>
5
+ <entity_type>Issue</entity_type>
6
+ <action>create</action>
7
+ <author id="1" name="Manager"/>
8
+ <api_includes>[]</api_includes>
9
+ <created_at>2017-08-18T11:56:53Z</created_at>
10
+ <updated_at>2019-08-29T07:44:16Z</updated_at>
11
+ </easy_web_hook>
@@ -0,0 +1,31 @@
1
+ RSpec.describe Easy::Resources::Redmine::CustomField do
2
+ include_context "redmine active resource shares" do
3
+ let(:entity_name) { 'custom_field' }
4
+ end
5
+
6
+ let(:entity) { find_entity }
7
+
8
+ describe "#cast_value" do
9
+ subject { entity.cast_value }
10
+ context "with datetime" do
11
+ let(:entity) { find_entity "datetime" }
12
+ it { is_expected.to be_a DateTime }
13
+ end
14
+ context "with date" do
15
+ let(:entity) { find_entity "date" }
16
+ it { is_expected.to be_a Date }
17
+ end
18
+ context "with int" do
19
+ let(:entity) { find_entity "int" }
20
+ it { is_expected.to eq 0 }
21
+ end
22
+ context "with float" do
23
+ let(:entity) { find_entity "float" }
24
+ it { is_expected.to eq 24.0 }
25
+ end
26
+ context "with text" do
27
+ let(:entity) { find_entity "string" }
28
+ it { is_expected.not_to be_blank }
29
+ end
30
+ end
31
+ end
@@ -10,5 +10,4 @@ RSpec.describe Easy::Resources::Redmine::EasyAttendance do
10
10
  it 'has user' do
11
11
  expect(find_entity.user).to be_a Easy::Resources::Redmine::User
12
12
  end
13
-
14
13
  end
@@ -22,5 +22,4 @@ RSpec.describe Easy::Resources::Redmine::EasyContact do
22
22
  # it '#demo?' do
23
23
  # expect(find_entity.demo?).to be_falsey
24
24
  # end
25
-
26
25
  end
@@ -3,7 +3,6 @@ RSpec.describe Easy::Resources::Redmine::EasyCrmCase do
3
3
  let(:entity_name) { 'easy_crm_case' }
4
4
  end
5
5
 
6
-
7
6
  it 'get crm case' do
8
7
  expect(find_entity.name).not_to be_empty
9
8
  end
@@ -15,5 +14,4 @@ RSpec.describe Easy::Resources::Redmine::EasyCrmCase do
15
14
  it 'crm case has customer' do
16
15
  expect(find_entity.customer).to be_a Easy::Resources::Redmine::EasyContact
17
16
  end
18
-
19
17
  end
@@ -12,5 +12,4 @@ RSpec.describe Easy::Resources::Redmine::EasyServer do
12
12
  subject.status = "stopped"
13
13
  expect(subject.server_status).to eq "stopped"
14
14
  end
15
-
16
15
  end
@@ -2,5 +2,4 @@ RSpec.describe Easy::Resources::Redmine::EasyWebApplicationActivity do
2
2
  include_context "redmine active resource shares" do
3
3
  let(:entity_name) { 'easy_web_application_activity' }
4
4
  end
5
-
6
5
  end
@@ -16,7 +16,7 @@ RSpec.describe Easy::Resources::Redmine::EasyWebApplication do
16
16
  end
17
17
 
18
18
  it 'get ewa' do
19
- expect(find_entity.attributes).to include *%w[id url git_repository version application_type created_at]
19
+ expect(find_entity.attributes).to include(*%w[id url git_repository version application_type created_at])
20
20
  expect(find_entity.git_branch).to be_nil
21
21
  expect(find_entity.name).not_to be_empty
22
22
  end
@@ -29,7 +29,6 @@ RSpec.describe Easy::Resources::Redmine::EasyWebApplication do
29
29
  include_examples "optional reference", :easy_contact
30
30
 
31
31
  describe ".get_all" do
32
-
33
32
  it "with block" do
34
33
  stub_xml(path: "easy_web_applications.xml", source_file: "index", response_headers: { 'Total' => '4' })
35
34
  stub_xml(path: "easy_web_applications.xml?page=2", source_file: "index")
@@ -53,7 +52,19 @@ RSpec.describe Easy::Resources::Redmine::EasyWebApplication do
53
52
  subject.easy_web_application_activities_attributes = { activities_count_in_day: 13 }
54
53
  subject.save
55
54
  end
55
+ end
56
56
 
57
+ describe "application_moves_on_request?" do
58
+ subject { find_entity.application_moves_on_request? }
59
+ it "should be true" do
60
+ is_expected.to be_truthy
61
+ end
57
62
  end
58
63
 
64
+ describe "application_updates_on_request?" do
65
+ subject { find_entity.application_updates_on_request? }
66
+ it "should be false" do
67
+ is_expected.to be_falsey
68
+ end
69
+ end
59
70
  end
@@ -0,0 +1,9 @@
1
+ RSpec.describe Easy::Resources::Redmine::EasyWebHook do
2
+ include_context "redmine active resource shares" do
3
+ let(:entity_name) { 'easy_web_hook' }
4
+ end
5
+
6
+ it "#status" do
7
+ expect(find_entity.status).to eq "inactive"
8
+ end
9
+ end
@@ -11,5 +11,4 @@ RSpec.describe Easy::Resources::Redmine::Errors do
11
11
  expect(time_entry.errors).to be_a described_class
12
12
  expect(time_entry.errors.full_messages).to eq ["Projekt je neplatné"]
13
13
  end
14
-
15
14
  end
@@ -3,7 +3,6 @@ RSpec.describe Easy::Resources::Redmine::Issue do
3
3
  let(:entity_name) { 'issue' }
4
4
  end
5
5
 
6
-
7
6
  it 'get issue' do
8
7
  expect(find_entity.subject).not_to be_empty
9
8
  end
@@ -11,5 +10,4 @@ RSpec.describe Easy::Resources::Redmine::Issue do
11
10
  it 'issue has project' do
12
11
  expect(find_entity.project).to be_a Easy::Resources::Redmine::Project
13
12
  end
14
-
15
13
  end
@@ -3,9 +3,7 @@ RSpec.describe Easy::Resources::Redmine::Project do
3
3
  let(:entity_name) { 'project' }
4
4
  end
5
5
 
6
-
7
6
  it 'get project' do
8
7
  expect(find_entity.name).not_to be_empty
9
8
  end
10
-
11
9
  end
@@ -1,5 +1,4 @@
1
1
  RSpec.describe Easy::Resources::Redmine::RedmineBase do
2
-
3
2
  it 'no configuration specify' do
4
3
  described_class.site = nil
5
4
  described_class.api_key = nil
@@ -15,5 +14,4 @@ RSpec.describe Easy::Resources::Redmine::RedmineBase do
15
14
  expect(described_class.headers).to include "X-Redmine-API-Key" => "xxxx"
16
15
  end
17
16
  end
18
-
19
17
  end
@@ -10,5 +10,4 @@ RSpec.describe Easy::Resources::Redmine::TimeEntry do
10
10
  it 'has project' do
11
11
  expect(find_entity.project).to be_a Easy::Resources::Redmine::Project
12
12
  end
13
-
14
13
  end
@@ -3,7 +3,6 @@ RSpec.describe Easy::Resources::Redmine::User do
3
3
  let(:entity_name) { 'user' }
4
4
  end
5
5
 
6
-
7
6
  it 'get user' do
8
7
  expect(find_entity.mail).not_to be_empty
9
8
  end
@@ -15,5 +14,4 @@ RSpec.describe Easy::Resources::Redmine::User do
15
14
  # it 'issue has project' do
16
15
  # expect(find_entity.project).to be_a Easy::Resources::Redmine::Project
17
16
  # end
18
-
19
17
  end
@@ -1,6 +1,7 @@
1
1
  class DummyResource < Easy::Resource
2
2
  self.site = "easyredmine.com"
3
3
  self.format = :json
4
+
4
5
  end
5
6
  RSpec.describe Easy::Resource do
6
7
  subject { DummyResource.new({ id: 1 }, true) }
@@ -22,7 +23,6 @@ RSpec.describe Easy::Resource do
22
23
  expect(subject).to receive(:patch).with nil, {}, value.to_xml(root: "dummy-resource")
23
24
  subject.update_column :att, 1
24
25
  end
25
-
26
26
  end
27
27
 
28
28
  describe "#patch" do
@@ -39,4 +39,4 @@ RSpec.describe Easy::Resource do
39
39
  subject.patch "deployed"
40
40
  end
41
41
  end
42
- end
42
+ end
data/spec/spec_helper.rb CHANGED
@@ -1,8 +1,11 @@
1
1
  ENV["RAILS_ENV"] = "test"
2
2
  require "simplecov"
3
3
  SimpleCov.start 'rails' do
4
- add_filter 'lib/easy/resources/spec_helper'
5
- add_filter 'lib/easy/resources/version'
4
+ add_filter '/bin'
5
+ add_filter '/lib/easy/resources/spec_helper'
6
+ add_filter '/lib/easy/resources/version'
7
+ add_filter '/spec/dummy'
8
+ add_filter '/vendor'
6
9
  end
7
10
 
8
11
  require "bundler/setup"
@@ -16,7 +19,6 @@ require "active_resource_response/http_mock"
16
19
  Dir["./spec/support/**/*.rb"].sort.each { |f| require f }
17
20
 
18
21
  RSpec.configure do |config|
19
-
20
22
  # Disable RSpec exposing methods globally on `Module` and `main`
21
23
  config.disable_monkey_patching!
22
24
 
@@ -24,4 +26,3 @@ RSpec.configure do |config|
24
26
  c.syntax = :expect
25
27
  end
26
28
  end
27
-
@@ -2,7 +2,7 @@ RSpec.shared_context "active resource shares", shared_context: :metadata do
2
2
  let(:site) { 'https://test.dummy' }
3
3
  let(:api_key) { 'secret' }
4
4
 
5
- let(:entity_name) {}
5
+ let(:entity_name) { "" }
6
6
 
7
7
  before(:each) do
8
8
  ActiveResource::HttpMock.reset!
@@ -23,6 +23,6 @@ RSpec.shared_context "redmine active resource shares", shared_context: :metadata
23
23
  options[:request_headers]["X-Redmine-API-Key"] = api_key
24
24
  options[:format] = format
25
25
  options[:path] = path
26
- stub_resource_request options
26
+ stub_resource_request(**options)
27
27
  end
28
- end
28
+ end
metadata CHANGED
@@ -1,15 +1,44 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: easy-resources
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.8.2
4
+ version: 0.10.1
5
5
  platform: ruby
6
6
  authors:
7
- - petr
7
+ - Petr
8
+ - Lukáš
8
9
  autorequire:
9
10
  bindir: bin
10
11
  cert_chain: []
11
- date: 2021-03-05 00:00:00.000000000 Z
12
+ date: 2021-09-03 00:00:00.000000000 Z
12
13
  dependencies:
14
+ - !ruby/object:Gem::Dependency
15
+ name: activeresource
16
+ requirement: !ruby/object:Gem::Requirement
17
+ requirements:
18
+ - - "~>"
19
+ - !ruby/object:Gem::Version
20
+ version: '5.1'
21
+ type: :runtime
22
+ prerelease: false
23
+ version_requirements: !ruby/object:Gem::Requirement
24
+ requirements:
25
+ - - "~>"
26
+ - !ruby/object:Gem::Version
27
+ version: '5.1'
28
+ - !ruby/object:Gem::Dependency
29
+ name: activeresource-response
30
+ requirement: !ruby/object:Gem::Requirement
31
+ requirements:
32
+ - - "~>"
33
+ - !ruby/object:Gem::Version
34
+ version: '1.2'
35
+ type: :runtime
36
+ prerelease: false
37
+ version_requirements: !ruby/object:Gem::Requirement
38
+ requirements:
39
+ - - "~>"
40
+ - !ruby/object:Gem::Version
41
+ version: '1.2'
13
42
  - !ruby/object:Gem::Dependency
14
43
  name: railties
15
44
  requirement: !ruby/object:Gem::Requirement
@@ -25,41 +54,41 @@ dependencies:
25
54
  - !ruby/object:Gem::Version
26
55
  version: '0'
27
56
  - !ruby/object:Gem::Dependency
28
- name: activeresource
57
+ name: rexml
29
58
  requirement: !ruby/object:Gem::Requirement
30
59
  requirements:
31
60
  - - "~>"
32
61
  - !ruby/object:Gem::Version
33
- version: '5.0'
62
+ version: 3.2.5
34
63
  type: :runtime
35
64
  prerelease: false
36
65
  version_requirements: !ruby/object:Gem::Requirement
37
66
  requirements:
38
67
  - - "~>"
39
68
  - !ruby/object:Gem::Version
40
- version: '5.0'
69
+ version: 3.2.5
41
70
  - !ruby/object:Gem::Dependency
42
- name: activeresource-response
71
+ name: easy-configuration
43
72
  requirement: !ruby/object:Gem::Requirement
44
73
  requirements:
45
- - - "~>"
74
+ - - ">="
46
75
  - !ruby/object:Gem::Version
47
- version: '1.2'
76
+ version: '0'
48
77
  type: :runtime
49
78
  prerelease: false
50
79
  version_requirements: !ruby/object:Gem::Requirement
51
80
  requirements:
52
- - - "~>"
81
+ - - ">="
53
82
  - !ruby/object:Gem::Version
54
- version: '1.2'
83
+ version: '0'
55
84
  - !ruby/object:Gem::Dependency
56
- name: easy-configuration
85
+ name: easy_style
57
86
  requirement: !ruby/object:Gem::Requirement
58
87
  requirements:
59
88
  - - ">="
60
89
  - !ruby/object:Gem::Version
61
90
  version: '0'
62
- type: :runtime
91
+ type: :development
63
92
  prerelease: false
64
93
  version_requirements: !ruby/object:Gem::Requirement
65
94
  requirements:
@@ -72,69 +101,73 @@ dependencies:
72
101
  requirements:
73
102
  - - "~>"
74
103
  - !ruby/object:Gem::Version
75
- version: '5.2'
104
+ version: '6.1'
76
105
  type: :development
77
106
  prerelease: false
78
107
  version_requirements: !ruby/object:Gem::Requirement
79
108
  requirements:
80
109
  - - "~>"
81
110
  - !ruby/object:Gem::Version
82
- version: '5.2'
111
+ version: '6.1'
83
112
  - !ruby/object:Gem::Dependency
84
113
  name: rspec-rails
85
114
  requirement: !ruby/object:Gem::Requirement
86
115
  requirements:
87
116
  - - "~>"
88
117
  - !ruby/object:Gem::Version
89
- version: '3.8'
118
+ version: '4.0'
90
119
  type: :development
91
120
  prerelease: false
92
121
  version_requirements: !ruby/object:Gem::Requirement
93
122
  requirements:
94
123
  - - "~>"
95
124
  - !ruby/object:Gem::Version
96
- version: '3.8'
125
+ version: '4.0'
97
126
  - !ruby/object:Gem::Dependency
98
- name: webmock
127
+ name: sqlite3
99
128
  requirement: !ruby/object:Gem::Requirement
100
129
  requirements:
101
130
  - - "~>"
102
131
  - !ruby/object:Gem::Version
103
- version: '3.4'
132
+ version: 1.4.2
104
133
  type: :development
105
134
  prerelease: false
106
135
  version_requirements: !ruby/object:Gem::Requirement
107
136
  requirements:
108
137
  - - "~>"
109
138
  - !ruby/object:Gem::Version
110
- version: '3.4'
139
+ version: 1.4.2
111
140
  - !ruby/object:Gem::Dependency
112
- name: sqlite3
141
+ name: webmock
113
142
  requirement: !ruby/object:Gem::Requirement
114
143
  requirements:
115
144
  - - "~>"
116
145
  - !ruby/object:Gem::Version
117
- version: 1.3.6
146
+ version: '3.13'
118
147
  type: :development
119
148
  prerelease: false
120
149
  version_requirements: !ruby/object:Gem::Requirement
121
150
  requirements:
122
151
  - - "~>"
123
152
  - !ruby/object:Gem::Version
124
- version: 1.3.6
125
- description: Description of Easy::Resources.
153
+ version: '3.13'
154
+ description: Define common Active::Resources for Redmine / Easy Redmine and Easy Project
155
+ entities.
126
156
  email:
127
157
  - petr@easy.cz
158
+ - lukas@easy.cz
128
159
  executables: []
129
160
  extensions: []
130
161
  extra_rdoc_files: []
131
162
  files:
163
+ - CHANGELOG.md
132
164
  - MIT-LICENSE
133
165
  - README.md
134
166
  - Rakefile
135
167
  - lib/easy/resource.rb
136
168
  - lib/easy/resources.rb
137
169
  - lib/easy/resources/railtie.rb
170
+ - lib/easy/resources/redmine/custom_field.rb
138
171
  - lib/easy/resources/redmine/easy_attendance.rb
139
172
  - lib/easy/resources/redmine/easy_contact.rb
140
173
  - lib/easy/resources/redmine/easy_crm_case.rb
@@ -151,6 +184,12 @@ files:
151
184
  - lib/easy/resources/spec_helper.rb
152
185
  - lib/easy/resources/version.rb
153
186
  - spec/easy_resources_spec.rb
187
+ - spec/fixtures/files/custom_field/bool.xml
188
+ - spec/fixtures/files/custom_field/date.xml
189
+ - spec/fixtures/files/custom_field/datetime.xml
190
+ - spec/fixtures/files/custom_field/float.xml
191
+ - spec/fixtures/files/custom_field/int.xml
192
+ - spec/fixtures/files/custom_field/string.xml
154
193
  - spec/fixtures/files/easy_attendance/show.xml
155
194
  - spec/fixtures/files/easy_contact.json
156
195
  - spec/fixtures/files/easy_contact/show.xml
@@ -165,6 +204,8 @@ files:
165
204
  - spec/fixtures/files/easy_web_application/with_easy_contact.xml
166
205
  - spec/fixtures/files/easy_web_application/with_easy_crm_case.xml
167
206
  - spec/fixtures/files/easy_web_application/with_ewaa.xml
207
+ - spec/fixtures/files/easy_web_hook/index.xml
208
+ - spec/fixtures/files/easy_web_hook/show.xml
168
209
  - spec/fixtures/files/issue.json
169
210
  - spec/fixtures/files/issue/show.xml
170
211
  - spec/fixtures/files/project.json
@@ -172,12 +213,14 @@ files:
172
213
  - spec/fixtures/files/time_entry/invalid_update.xml
173
214
  - spec/fixtures/files/time_entry/show.xml
174
215
  - spec/fixtures/files/user/show.xml
216
+ - spec/models/easy-resources/redmine/custom_field_spec.rb
175
217
  - spec/models/easy-resources/redmine/easy_attendance_spec.rb
176
218
  - spec/models/easy-resources/redmine/easy_contact_spec.rb
177
219
  - spec/models/easy-resources/redmine/easy_crm_case_spec.rb
178
220
  - spec/models/easy-resources/redmine/easy_server_spec.rb
179
221
  - spec/models/easy-resources/redmine/easy_web_application_activity_spec.rb
180
222
  - spec/models/easy-resources/redmine/easy_web_application_spec.rb
223
+ - spec/models/easy-resources/redmine/easy_web_hook_spec.rb
181
224
  - spec/models/easy-resources/redmine/errors_spec.rb
182
225
  - spec/models/easy-resources/redmine/issue_spec.rb
183
226
  - spec/models/easy-resources/redmine/project_spec.rb
@@ -189,7 +232,7 @@ files:
189
232
  - spec/support/active_resource.rb
190
233
  - spec/support/fixtures.rb
191
234
  - spec/support/redmine_active_resource.rb
192
- homepage: https://www.easysoftware.com
235
+ homepage: https://git.easy.cz/easy/resources
193
236
  licenses:
194
237
  - MIT
195
238
  metadata:
@@ -202,54 +245,64 @@ required_ruby_version: !ruby/object:Gem::Requirement
202
245
  requirements:
203
246
  - - ">="
204
247
  - !ruby/object:Gem::Version
205
- version: '0'
248
+ version: '2.6'
206
249
  required_rubygems_version: !ruby/object:Gem::Requirement
207
250
  requirements:
208
251
  - - ">="
209
252
  - !ruby/object:Gem::Version
210
253
  version: '0'
211
254
  requirements: []
212
- rubygems_version: 3.0.8
255
+ rubygems_version: 3.2.19
213
256
  signing_key:
214
257
  specification_version: 4
215
- summary: Summary of Easy::Resources.
258
+ summary: ActiveResources connectors for Easy Project / Easy Redmine
216
259
  test_files:
217
- - spec/spec_helper.rb
218
- - spec/models/easy-resources/redmine/project_spec.rb
219
- - spec/models/easy-resources/redmine/easy_crm_case_spec.rb
220
- - spec/models/easy-resources/redmine/easy_contact_spec.rb
221
- - spec/models/easy-resources/redmine/issue_spec.rb
222
- - spec/models/easy-resources/redmine/time_entry_spec.rb
223
- - spec/models/easy-resources/redmine/redmine_base_spec.rb
224
- - spec/models/easy-resources/redmine/easy_web_application_activity_spec.rb
225
- - spec/models/easy-resources/redmine/easy_web_application_spec.rb
226
- - spec/models/easy-resources/redmine/easy_server_spec.rb
227
- - spec/models/easy-resources/redmine/errors_spec.rb
228
- - spec/models/easy-resources/redmine/user_spec.rb
229
- - spec/models/easy-resources/redmine/easy_attendance_spec.rb
230
- - spec/models/easy-resources/resource_spec.rb
231
- - spec/support/active_resource.rb
232
- - spec/support/fixtures.rb
233
- - spec/support/redmine_active_resource.rb
234
260
  - spec/easy_resources_spec.rb
261
+ - spec/fixtures/files/custom_field/bool.xml
262
+ - spec/fixtures/files/custom_field/date.xml
263
+ - spec/fixtures/files/custom_field/datetime.xml
264
+ - spec/fixtures/files/custom_field/float.xml
265
+ - spec/fixtures/files/custom_field/int.xml
266
+ - spec/fixtures/files/custom_field/string.xml
267
+ - spec/fixtures/files/easy_attendance/show.xml
235
268
  - spec/fixtures/files/easy_contact/show.xml
236
- - spec/fixtures/files/time_entry/show.xml
237
- - spec/fixtures/files/time_entry/invalid_update.xml
238
- - spec/fixtures/files/easy_crm_case.json
239
- - spec/fixtures/files/easy_crm_case/show.xml
240
- - spec/fixtures/files/project.json
241
- - spec/fixtures/files/issue.json
242
- - spec/fixtures/files/user/show.xml
243
- - spec/fixtures/files/project/show.xml
244
- - spec/fixtures/files/issue/show.xml
245
269
  - spec/fixtures/files/easy_contact.json
270
+ - spec/fixtures/files/easy_crm_case/show.xml
271
+ - spec/fixtures/files/easy_crm_case.json
246
272
  - spec/fixtures/files/easy_server/index.xml
247
273
  - spec/fixtures/files/easy_server/show.xml
248
- - spec/fixtures/files/easy_attendance/show.xml
249
274
  - spec/fixtures/files/easy_web_application/index.xml
250
- - spec/fixtures/files/easy_web_application/with_ewaa.xml
251
- - spec/fixtures/files/easy_web_application/with_custom_fields.xml
275
+ - spec/fixtures/files/easy_web_application/show.json
252
276
  - spec/fixtures/files/easy_web_application/show.xml
277
+ - spec/fixtures/files/easy_web_application/with_custom_fields.xml
253
278
  - spec/fixtures/files/easy_web_application/with_easy_contact.xml
254
279
  - spec/fixtures/files/easy_web_application/with_easy_crm_case.xml
255
- - spec/fixtures/files/easy_web_application/show.json
280
+ - spec/fixtures/files/easy_web_application/with_ewaa.xml
281
+ - spec/fixtures/files/easy_web_hook/index.xml
282
+ - spec/fixtures/files/easy_web_hook/show.xml
283
+ - spec/fixtures/files/issue/show.xml
284
+ - spec/fixtures/files/issue.json
285
+ - spec/fixtures/files/project/show.xml
286
+ - spec/fixtures/files/project.json
287
+ - spec/fixtures/files/time_entry/invalid_update.xml
288
+ - spec/fixtures/files/time_entry/show.xml
289
+ - spec/fixtures/files/user/show.xml
290
+ - spec/models/easy-resources/redmine/custom_field_spec.rb
291
+ - spec/models/easy-resources/redmine/easy_attendance_spec.rb
292
+ - spec/models/easy-resources/redmine/easy_contact_spec.rb
293
+ - spec/models/easy-resources/redmine/easy_crm_case_spec.rb
294
+ - spec/models/easy-resources/redmine/easy_server_spec.rb
295
+ - spec/models/easy-resources/redmine/easy_web_application_activity_spec.rb
296
+ - spec/models/easy-resources/redmine/easy_web_application_spec.rb
297
+ - spec/models/easy-resources/redmine/easy_web_hook_spec.rb
298
+ - spec/models/easy-resources/redmine/errors_spec.rb
299
+ - spec/models/easy-resources/redmine/issue_spec.rb
300
+ - spec/models/easy-resources/redmine/project_spec.rb
301
+ - spec/models/easy-resources/redmine/redmine_base_spec.rb
302
+ - spec/models/easy-resources/redmine/time_entry_spec.rb
303
+ - spec/models/easy-resources/redmine/user_spec.rb
304
+ - spec/models/easy-resources/resource_spec.rb
305
+ - spec/spec_helper.rb
306
+ - spec/support/active_resource.rb
307
+ - spec/support/fixtures.rb
308
+ - spec/support/redmine_active_resource.rb