-
Notifications
You must be signed in to change notification settings - Fork 15
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
feat: add some very basic validation to Metric struct #18
Conversation
@@ -27,3 +27,15 @@ type DeviceMetric struct { | |||
Platform string `json:"platform"` | |||
PlatformVersion string `json:"platformVersion"` | |||
} | |||
|
|||
func (m *Metric) Validate() (valid bool, reason string) { | |||
if m.ClientId == "" { |
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.
will this be an empty string if not submitted or 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.
Looks like it can only be nil if it's a pointer: https://stackoverflow.com/questions/12703243/what-is-the-zero-for-string
Learning this now myself too :D
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.
Thanks, good to know! I have not much of an Idea about Golang ;)
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 part of decoding JSON into a struct, if a field is omitted it is instantiated with it's 'zero' value. The zero value for a string is "".
You see later on that we check if m.Data is nil. That's because the Data field expects a type *MetricData which is a pointer as opposed to the value itself. The zero value of a pointer is nil, hence the nil check for metric.Data but empty string check for ClientId. Does that make sense @pb82 ?
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.
@darahayes yes makes sense, thanks for explaining that
Name: "Empty metric should be invalid", | ||
Metric: Metric{}, | ||
Valid: false, | ||
ExpectedReason: "missing clientId in payload", |
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.
shouldn't the message be empty metric is invalid
?
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.
The validate function executes checks in sequence where the first check is the clientId. For that reason this was the behaviour I intended. Happy to change it it but I think it's good
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 was just going by the name of the test which mentions Empty metrics
. I guess missing clientId
is still correct in that case.
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.
LGTM, just a small comment
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.
Verified locally
@darahayes do you think it would be worthwhile converting your curl statements into integration tests? |
Definitely. I'm going to create a ticket for e2e style tests that will behave in this way. |
Description
This PR adds a function
Validate() (valid bool, reason string)
to the Metric struct and uses that function in the metrics handler to check for some basic validation cases. clientId not existing and Data not existing or being empty object.This prevents us from saving empty entries in postgres. Unit tests have been added for the Validate() function.
Verification steps
I've constructed some curl requests and expected responses so you can try out. For now the server returns the same data that is saved in the DB. This is handy in development.
Case 1
The happy case - full payload. (Excluding client timestamp - will look after this in a separate PR)
result:
Case 2
app data is included but not device metrics. i.e. only a subset of all possible fields, but still valid.
result:
Case 3
Client sends an empty object:
Result:
Case 4
Data field is not included
result:
Case 5
Data field is there but empty object
result: