-
Notifications
You must be signed in to change notification settings - Fork 10
[CRYSTAL-368]Enforce cov2 limits in requirment validations #383
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
[CRYSTAL-368]Enforce cov2 limits in requirment validations #383
Conversation
d8fb91b
to
5516c54
Compare
I haven't added these comments everywhere; they apply to every place where the scenario matches. |
Could you please include the final requirements structure in the description including all the required keys? It would be very helpful during the review process. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Nice work! I'm still reviewing the PR and should be adding more comments later.
@digesh-parecha @mmassaki Added final requirements structure in the description including all the required keys. And I did found the missing validations for required keys in triggers, will add those in next commit. |
3d74473
to
2bbe4b5
Compare
object_fields = requirements[SCHEMA_KEYS[:object_fields]] | ||
object_triggers = requirements[SCHEMA_KEYS[:object_triggers]] | ||
|
||
if all_collections_empty_or_nil?(objects, object_fields, object_triggers) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is there any dependency among objects, object_fields, and object_triggers?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
- No dependency in validation logic. Each collection validates independently.
- fields/triggers reference object_key but we don't enforce those validations here (will be done in classic). This service only handles COV2 limits, structural type and payload size validation.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
fields/triggers reference object_key but we don't enforce those validations here.
- Curious to know When will this validation be performed?
- Will it allow submitting the app when there are mismatched keys between the object and the object_key in object_fields?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes, current code will allow submitting the object_fields and object_triggers with invalid object references.
By invalid, I mean object_keys which does not exists in objects
array.
But I will address it in next PR(Draft)
This is because it has new translation key which would take another week to be translated,hence will address this issue in next PR once translations are available.
end | ||
|
||
[ | ||
validate_collection_is_array(objects, :invalid_objects_structure_in_cov2_requirements), |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
validate_collection_is_array
and all_collections_empty_or_nil
seem to do the same thing. Can we combine them into a single function?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
They serve different purposes and can't be combined:
-
all_collections_empty_or_nil
: returns early if all the arrays objects, fields, triggers are empty with correct error message because there is nothing to install -
validate_collection_is_array
: is for type safety of objects, fields, triggers array. It is crucial in cases below
where requirements contains only objects so we need to ensure its also an array.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
As discussed, let's check the possibly to combine this two methods.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@digesh-parecha I want to clarify my earlier response which caused the confusion
all_collections_empty?
: It catches the specific case where someone provides
{"objects":[], "object_fields":[], "object_triggers":[]}
and returns an empty_cov2_requirements
error because there's nothing meaningful to install
validate_collection_is_array
: validates that each field is an array and raise error for string/number/etc.) but allows empty arrays [] to pass through because this is valid requirement: {"objects":[.....], "object_fields":[], "object_triggers":[]}
I prefer to keep these validations separate since they serve different purposes
def valid_conditions_structure?(conditions) | ||
return false unless conditions.is_a?(Hash) | ||
|
||
(conditions.key?('all') || conditions.key?('any')) && |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
What is the purpose of the condition (conditions.key?('all') || conditions.key?('any'))
?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
- It ensures either
all
orany
key is present in conditions hash - then next line check is all
or
any` key is present in conditions hash then it must be an array
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Implementation is changed now
return false unless conditions.is_a?(Hash) | ||
|
||
(conditions.key?('all') || conditions.key?('any')) && | ||
CONDITION_KEYS.all? { |key| conditions[key].nil? || conditions[key].is_a?(Array) } |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
How about to simplify the entire condition like this?
CONDITION_KEYS.all? { |key| conditions[key].nil? || conditions[key].is_a?(Array) } | |
CONDITION_KEYS.any? { |key| conditions[key].is_a?(Array) } |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If we use .any?
, then a conditions hash like { "all" => [], "any" => "not_an_array" }
would be considered valid, which is not correct
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
As discussed, See if it’s possible to have a single check that performs both validations.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Changed the implementation
let(:custom_objects_v2_requirements) { nil } | ||
let(:errors) { described_class.call(custom_objects_v2_requirements) } | ||
|
||
context 'when custom objects v2 requirements is not a hash' do |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'd recommend a more specific description to make the intent clear.
context 'when custom objects v2 requirements is not a hash' do | |
context 'when custom objects v2 requirements is an array' do |
require 'json' | ||
|
||
describe ZendeskAppsSupport::Validations::CustomObjectsV2 do | ||
let(:custom_objects_v2_requirements) { nil } |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Do we have a test example for when custom_objects_v2_requirements
is nil
?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
No, this is an invalid test CustomObjectsV2 will not receive a nil
value
|
||
# ========== OBJECTS VALIDATION ========== | ||
|
||
def validate_objects_excessive_limit(objects = []) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Sorry, I was wrong this comment.
I realized default args in ruby are only used when the arg is not defined, which makes it redundant as this method is never called without it.
This also applies to other methods in this class.
def validate_objects_excessive_limit(objects = []) | |
def validate_objects_excessive_limit(objects) |
💐
/cc @zendesk/wattle
Description
Note : Translations are already merged with main.
The PR implements validation limits on Custom Objects V2 requirements in ZAS
Custom Objects V2 requirements = Custom Objects v2 + custom object fields +custom object triggers
Requirement structure with required fields:
New Changes Introduced
custom_objects_v2
as a valid type in requirement.jsonCustomObjectsV2
Validation Limits Enforced
Object Limits
Field Limits
Trigger Limits
Payload Size Limits
Validation Flow
References
JIRA
RFC
Before merging this PR
Risks
No, it cannot affect apps rendering for user because code changes in this PR are not yet used for app validations. We'll uncomment the once translations for validation errors are available.
medium: Right now, it does not touch any existing feature. We are introducing a new
resource_type
which is not yet used in ZAM or any of the existing apps.