alula-ruby 1.1.0 → 1.2.1

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: f16a5d5af860eb10eb005fd515b1f3a5c14054c10f893399311fa265288da01e
4
- data.tar.gz: 31e9bc85d0883308067b14df4b199813f19eb67a039474bcb263d79a4dc9381d
3
+ metadata.gz: 546e50f62f86038f53f08d44774263b5adce9d74b5ea2fa4d2795195e3f93877
4
+ data.tar.gz: ad18a4e2275bc8811c89c5d1ae00514757e6e39808fe9d8176847f6b85779bf7
5
5
  SHA512:
6
- metadata.gz: bea969dc3209e921a2e3f011a9e5186713274ab6071666b4a03ba4f77eeaabd5cf6102f7053fe2e82afdb09c28301dd2313fc6aadec1627dd5deadde5472ec30
7
- data.tar.gz: 0fba4a8346c91cb940c98739263cba2d73121b8c3045bf49716c1b440b98b7917357ec6fd3a37263b8afafa30c65210f7e50bdd644d089de7428747c4169665a
6
+ metadata.gz: a19f8278b5db084bfae605d419bac5511cc6a0e260c985f002ed8827bad68d27658ee59e9faf2dc33fe9d301eee270ccb8cf83dd85c8a134a5c0edbcf058f59a
7
+ data.tar.gz: 5803162edb7262f6f56e155503d13bd4b77036b02de069fabc6f37a0e622a92e7c3c40c73fbdf96b32696e5e4174b58cecd658f8271120e1004956e1020f7680
data/README.md CHANGED
@@ -386,7 +386,22 @@ To install this gem onto your local machine, run `bundle exec rake install`. To
386
386
 
387
387
  Alula Ruby runs its unit & integratin tests against a copy of the API running in Docker. The remote API is cleaned up (DB truncated & re-seeded fresh) between every `describe` or `context` block.
388
388
 
389
- 1. Set up local Core API cluster/swarm using `make`:
389
+ 1. Authenticate with AWS
390
+
391
+ Set the registry account number to refer to
392
+
393
+ ```bash
394
+ export AWS_ECR_REGISTRY_ID=613707345027 #409473619697
395
+ ```
396
+
397
+ Then execute AWS login where the `$env` is whatever profile name your Shared Services account is setup under in AWS CLI SSO.
398
+
399
+ ```bash
400
+ aws ecr get-login-password --profile $env | docker login \
401
+ --username AWS --password-stdin $AWS_ECR_REGISTRY_ID.dkr.ecr.$AWS_REGION.amazonaws.com
402
+ ```
403
+
404
+ 2. Set up local Core API cluster/swarm using `make`:
390
405
 
391
406
  make up
392
407
 
@@ -394,29 +409,37 @@ Alula Ruby runs its unit & integratin tests against a copy of the API running in
394
409
 
395
410
  alula-docker-compose -I @test-helper --registry '6z1wlx5zf1.execute-api.us-east-1.amazonaws.com/' -- up -d
396
411
 
397
- Note: You do need to be authorized against our private ECR registry. This is manual, talk with an Alula Lead to get pointed in the right direction. TODO: Write out what we need to do for this.
412
+ Note: You do need to be authorized against our private ECR registry. This is manual, talk with an Alula Lead to get pointed in the right direction. TODO: Write out what we need to do for this.
398
413
 
399
- 1. Configure your local .env file, you can copy-paste `.env.example` over to `.env`
414
+ 1. Configure your local .env file, you can copy-paste `.env.example` over to `.env`
400
415
 
401
- 1. Run the complete test suite:
416
+ 1. Run the complete test suite:
402
417
 
403
- `bundle exec rspec`
418
+ `bundle exec rspec`
404
419
 
405
- 1. Run a specific test file:
420
+ 1. Run a specific test file:
406
421
 
407
422
  `bundle exec rspec ./spec/alula/oauth_spec.rb`
408
423
 
409
- 1. Run Guard to have tests run on file change
424
+ 1. Run Guard to have tests run on file change
410
425
 
411
426
  `bundle exec guard`
412
427
 
413
- 1. Update all Docker images to the latest images:
428
+ 1. If you're using the Ruby Test Explorer extension to run the tests within VS Code, SimpleCov has a dry run error preventing auto detection. You need to turn off minimum coverage to get the dry run command it uses to find tests to work.
429
+
430
+ ```ruby
431
+ SimpleCov.start do
432
+ add_filter '/spec/'
433
+ minimum_coverage 0
434
+ end
435
+ ```
436
+
437
+ 1. Update all Docker images to the latest images:
414
438
 
415
439
  `docker compose -f alula-docker-compose.yml pull`
416
440
 
417
441
  Occasionally under heavy use the dockerized API may lose or drop its databases, resulting in the test suite erroring completly and very quickly. To fix this simply restart the API with `docker-compose -f alula-docker-compose.yml down && docker-compose -f alula-docker-compose.yml up -d`
418
442
 
419
-
420
443
  ## Importing GEM in AC Docker
421
444
 
422
445
  Most of the times, the work we do in alula ruby includes just updating the model/procedures and push the changes, without having to worry about the configuration mentioned above. When we make changes to alula ruby locally we need to test if the gem file works.
data/VERSION.md CHANGED
@@ -2,10 +2,12 @@
2
2
 
3
3
  | Version | Date | Description |
4
4
  | ------- | --------- | --------------------------------------------------------------------------- |
5
- | v1.1.0 | 2023-08-01 | Fixes Ruby 3 argument errors in filter builder. Gets test suite running again in circle |
6
- | v1.0.2 | 2023-05-30 | Includes v0.69.11 - fix for a field not being underscoreable |
7
- | v1.0.1 | 2023-05-30 | Includes v0.69.10 |
8
- | v1.0.0 | 2023-05-30 | Ruby 3 support with some breaking changes |
5
+ | v1.2.1 | 2023-08-17 | Fix types on OAuth clients |
6
+ | v1.2.0 | 2023-08-10 | Support objects and saving to objects natively |
7
+ | v1.1.0 | 2023-08-01 | Fixes Ruby 3 argument errors in filter builder. Gets test suite running again in circle |
8
+ | v1.0.2 | 2023-05-30 | Includes v0.69.11 - fix for a field not being underscoreable |
9
+ | v1.0.1 | 2023-05-30 | Includes v0.69.10 |
10
+ | v1.0.0 | 2023-05-30 | Ruby 3 support with some breaking changes |
9
11
  | v0.69.10| 2023-06-14 | Dealer phone relationship |
10
12
  | v0.69.9 | 2023-04-18 | Dealer Program resource update |
11
13
  | v0.69.8 | 2023-03-29 | Use isCamera and isPanel API fields |
@@ -99,6 +99,8 @@ module Alula
99
99
  else
100
100
  obj[key] = val.to_s
101
101
  end
102
+ elsif val.is_a? Alula::ObjectField
103
+ obj[key] = val.as_json
102
104
  else
103
105
  obj[key] = val
104
106
  end
@@ -182,16 +182,28 @@ module Alula
182
182
  # Transform the field name into an API-valid lowerCamelCase
183
183
  # format and return it.
184
184
  def validate_field_filterability!(field_name)
185
+
186
+ # Use the parent of a features_selected.alarm_transmission (features_selected) to check filterability
185
187
  underscored = Util.underscore(field_name).to_sym
188
+ mod_field_name = underscored.to_s.split('.')[0].to_sym
189
+
190
+ # Used to save the actual where, so we don't use the parent object here
186
191
  camelized = Util.camelize(underscored).to_s
187
192
 
188
- unless model_class.get_fields.include?(underscored)
189
- error = "Field `#{underscored}` does not exist resource `#{model_class}`"
193
+ unless model_class.get_fields.include?(mod_field_name)
194
+ error = "Field `#{mod_field_name}` does not exist resource `#{model_class}`"
195
+ raise Alula::InvalidFilterFieldError.new(error)
196
+ end
197
+
198
+ unless model_class.filterable_fields.include?(mod_field_name)
199
+ error = "Field `#{mod_field_name}` is not filterable on resource `#{model_class}`"
190
200
  raise Alula::InvalidFilterFieldError.new(error)
191
201
  end
192
202
 
193
- unless model_class.filterable_fields.include?(underscored)
194
- error = "Field `#{underscored}` is not filterable on resource `#{model_class}`"
203
+ # Make sure that we are filtering on the actual field name, not the parent
204
+ field_settings = model_class.get_fields[mod_field_name]
205
+ if field_settings[:type] == :object && field_settings[:use] && underscored.to_s.split('.').length == 1
206
+ error = "Field `#{mod_field_name}` is not filterable on resource `#{model_class}`. Please specify child property"
195
207
  raise Alula::InvalidFilterFieldError.new(error)
196
208
  end
197
209
 
@@ -203,16 +215,28 @@ module Alula
203
215
  # Transform the field name into an API-validated lowerCamelCase
204
216
  # TODO: This doesn't belong here, should be on its own include I think
205
217
  def validate_field_sortability!(field_name)
218
+
219
+ # Use the parent of a features_selected.alarm_transmission (features_selected) to check sortability
206
220
  underscored = Util.underscore(field_name).to_sym
221
+ mod_field_name = underscored.to_s.split('.')[0].to_sym
222
+
223
+ # Used to save the actual where, so we don't use the parent object here
207
224
  camelized = Util.camelize(underscored).to_s
208
225
 
209
- unless model_class.get_fields.include?(underscored)
210
- error = "Field `#{underscored}` does not exist resource `#{model_class}`"
211
- raise Alula::InvalidFilterFieldError.new(error)
226
+ unless model_class.get_fields.include?(mod_field_name)
227
+ error = "Field `#{mod_field_name}` does not exist resource `#{model_class}`"
228
+ raise Alula::InvalidSortFieldError.new(error)
212
229
  end
213
230
 
214
- unless model_class.sortable_fields.include?(underscored)
215
- error = "Field `#{underscored}` is not sortable on resource `#{model_class}`"
231
+ unless model_class.sortable_fields.include?(mod_field_name)
232
+ error = "Field `#{mod_field_name}` is not sortable on resource `#{model_class}`"
233
+ raise Alula::InvalidSortFieldError.new(error)
234
+ end
235
+
236
+ # Make sure that we are sorting on the actual field name, not the parent
237
+ field_settings = model_class.get_fields[mod_field_name]
238
+ if field_settings[:type] == :object && field_settings[:use] && underscored.to_s.split('.').length == 1
239
+ error = "Field `#{mod_field_name}` is not sortable on resource `#{model_class}`. Please specify child property"
216
240
  raise Alula::InvalidSortFieldError.new(error)
217
241
  end
218
242
 
@@ -7,6 +7,10 @@ module Alula
7
7
  @type = nil
8
8
  @http_methods = []
9
9
  @fields = {}
10
+
11
+ def mark_dirty(field_name, old_value, new_value)
12
+ @dirty_attributes << field_name if old_value != new_value
13
+ end
10
14
  end
11
15
  base.include(InstanceMethods)
12
16
  end
@@ -60,6 +64,8 @@ module Alula
60
64
  rescue ArgumentError
61
65
  value
62
66
  end
67
+ elsif opts[:type] == :object && opts[:use] && !value.nil? && value.respond_to?(:each)
68
+ opts[:use].new(@dirty_attributes, field_name, value)
63
69
  elsif opts[:type] == :boolean
64
70
  [true, 'true', 1, '1'].include? value
65
71
  elsif opts[:symbolize] == true
@@ -87,16 +93,12 @@ module Alula
87
93
  new_value = [true, 'true', 1, '1'].include? new_value
88
94
  end
89
95
 
90
- #
91
96
  # Mark the attribute as dirty if the new value is different
92
- @dirty_attributes << field_name if @values[jsonKey] != new_value
93
-
97
+ mark_dirty(field_name, @values[jsonKey], new_value)
94
98
  #
95
99
  # Assign the new value (always assigned even if a duplicate)
96
100
  @values[jsonKey] = new_value
97
101
  end
98
-
99
-
100
102
  end
101
103
  end
102
104
 
@@ -200,4 +202,47 @@ module Alula
200
202
  end
201
203
  end
202
204
  end
205
+
206
+ class ObjectField
207
+ extend ResourceAttributes
208
+
209
+ # Assume properties is camel case
210
+ def initialize(dirty_attributes, parent_field, properties = {})
211
+ @values = properties
212
+ @parent_dirty_attributes = dirty_attributes
213
+ @parent_field = parent_field
214
+ # Not used, just to make resource attributes happy
215
+ @dirty_attributes = Set.new
216
+
217
+ return unless properties
218
+ valid_fields = self.class.get_fields
219
+
220
+ properties.dup.each do |key, value|
221
+ jsonKey = key;
222
+ ruby_key = Alula::Util.underscore(key.to_s)
223
+
224
+ self.public_send("#{ruby_key}=", value) if valid_fields.key?(ruby_key.to_sym)
225
+ end
226
+ end
227
+ def mark_dirty(field_name, old_value, new_value)
228
+ @parent_dirty_attributes << @parent_field if old_value != new_value
229
+ end
230
+
231
+ def as_json
232
+ self.field_names.each_with_object({}) do |ruby_key, obj|
233
+ key = Util.camelize(ruby_key)
234
+ val = self.send(ruby_key)
235
+
236
+ if self.date_fields.include?(ruby_key) && ![nil, ''].include?(val)
237
+ if val.respond_to? :strftime
238
+ obj[key] = val.strftime('%Y-%m-%dT%H:%M:%S.%L%z')
239
+ else
240
+ obj[key] = val.to_s
241
+ end
242
+ else
243
+ obj[key] = val
244
+ end
245
+ end
246
+ end
247
+ end
203
248
  end
@@ -7,6 +7,18 @@ module Alula
7
7
  extend Alula::ApiOperations::Save
8
8
 
9
9
  include Alula::DeviceAttributeTranslations
10
+
11
+
12
+ class FeaturesSelected < Alula::ObjectField
13
+ field :alarm_transmission, type: :boolean
14
+ field :alarm_notifications, type: :boolean
15
+ field :interactive_services, type: :boolean
16
+ field :home_automation, type: :boolean
17
+ field :two_way_voice, type: :boolean
18
+ field :vigilance, type: :boolean
19
+ field :alarm_verification, type: :boolean
20
+ field :alula_messenger, type: :boolean
21
+ end
10
22
 
11
23
  resource_path 'devices'
12
24
  type 'devices'
@@ -443,9 +455,10 @@ module Alula
443
455
  field :features_selected,
444
456
  type: :object,
445
457
  sortable: false,
446
- filterable: false,
458
+ filterable: true,
447
459
  creatable_by: [],
448
- patchable_by: []
460
+ patchable_by: [:system, :station, :dealer, :technician],
461
+ use: FeaturesSelected
449
462
 
450
463
  field :any_trouble,
451
464
  type: :boolean,
@@ -678,60 +691,5 @@ module Alula
678
691
  creatable_by: [],
679
692
  patchable_by: []
680
693
 
681
- field 'features_selected.alarm_transmission'.to_sym,
682
- type: :boolean,
683
- sortable: false,
684
- filterable: true,
685
- creatable_by: [],
686
- patchable_by: []
687
-
688
- field 'features_selected.alarm_notifications'.to_sym,
689
- type: :boolean,
690
- sortable: false,
691
- filterable: true,
692
- creatable_by: [],
693
- patchable_by: []
694
-
695
- field 'features_selected.interactive_services'.to_sym,
696
- type: :boolean,
697
- sortable: false,
698
- filterable: true,
699
- creatable_by: [],
700
- patchable_by: []
701
-
702
- field 'features_selected.home_automation'.to_sym,
703
- type: :boolean,
704
- sortable: false,
705
- filterable: true,
706
- creatable_by: [],
707
- patchable_by: []
708
-
709
- field 'features_selected.two_way_voice'.to_sym,
710
- type: :boolean,
711
- sortable: false,
712
- filterable: true,
713
- creatable_by: [],
714
- patchable_by: []
715
-
716
- field 'features_selected.vigilance'.to_sym,
717
- type: :boolean,
718
- sortable: false,
719
- filterable: true,
720
- creatable_by: [],
721
- patchable_by: []
722
-
723
- field 'features_selected.alarm_verification'.to_sym,
724
- type: :boolean,
725
- sortable: false,
726
- filterable: true,
727
- creatable_by: [],
728
- patchable_by: []
729
-
730
- field 'features_selected.alula_messenger'.to_sym,
731
- type: :boolean,
732
- sortable: false,
733
- filterable: true,
734
- creatable_by: [],
735
- patchable_by: []
736
694
  end
737
695
  end
@@ -48,14 +48,14 @@ module Alula
48
48
  patchable_by: [:system]
49
49
 
50
50
  field :scope,
51
- type: :date,
51
+ type: :string,
52
52
  sortable: false,
53
53
  filterable: false,
54
54
  creatable_by: [:system],
55
55
  patchable_by: [:system]
56
56
 
57
57
  field :user_id,
58
- type: :date,
58
+ type: :string,
59
59
  sortable: false,
60
60
  filterable: true,
61
61
  creatable_by: [:system],
data/lib/alula/version.rb CHANGED
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Alula
4
- VERSION = '1.1.0'
4
+ VERSION = '1.2.1'
5
5
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: alula-ruby
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.1.0
4
+ version: 1.2.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Titus Johnson
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2023-08-02 00:00:00.000000000 Z
11
+ date: 2023-08-17 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: httparty