-
Notifications
You must be signed in to change notification settings - Fork 24
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Openapi property based testing (#172)
* first tries of property-based testing APIv3 * improve requests handling in CastAndValidate plug * cover missing field scenario; upgrade missing field response stub * refactor RequestsGenerator; remove stream_data dep from dev * ignore StreamData by dialyzer; #makeCircleCIGreenAgain * apply PR remarks ``` This PR introduces a property-based approach to APIv3 testing, with a little help of the `StreamData` framework. I also incorporated the fix/enhancement of 'the hack of the hack' introduced in #168. Shortly speaking, the request containing, from the needed fields, only data, alert/body and alert/title fields, was matched against SilentNotification schema, what has been leading to improper Unexpected field: alert error. I also improved the `ControllersHelper.missing_field_response` helper function to better reflect possible error messages we can encounter during tests, based on the API version being used. ```
- Loading branch information
Showing
9 changed files
with
194 additions
and
11 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,77 @@ | ||
defmodule MongoosePushWeb.Support.RequestsGenerator do | ||
# APIv2/3 requests | ||
def mandatory_fields() do | ||
StreamData.fixed_map(%{ | ||
"alert" => | ||
StreamData.fixed_map(%{ | ||
"title" => nonempty_string(), | ||
"body" => nonempty_string() | ||
}), | ||
"service" => service() | ||
}) | ||
end | ||
|
||
def optional_fields() do | ||
StreamData.optional_map(%{ | ||
"alert" => | ||
StreamData.optional_map(%{ | ||
"badge" => positive_integer(), | ||
"click_action" => nonempty_string(), | ||
"tag" => nonempty_string(), | ||
"sound" => nonempty_string() | ||
}), | ||
"data" => data(), | ||
"mode" => mode(), | ||
"priority" => priority(), | ||
"mutable_content" => boolean(), | ||
"tags" => tags(), | ||
"topic" => nonempty_string(), | ||
"time_to_live" => positive_integer() | ||
}) | ||
end | ||
|
||
def device_id() do | ||
nonempty_string() | ||
end | ||
|
||
def mandatory_field() do | ||
one_of_strings([:service, :title, :body]) | ||
end | ||
|
||
# basic types | ||
defp nonempty_string() do | ||
StreamData.string(:alphanumeric, min_length: 1) | ||
end | ||
|
||
defp positive_integer() do | ||
StreamData.positive_integer() | ||
end | ||
|
||
defp boolean() do | ||
StreamData.one_of([false, true]) | ||
end | ||
|
||
defp tags() do | ||
StreamData.list_of(nonempty_string(), min_length: 1, max_length: 5) | ||
end | ||
|
||
defp priority() do | ||
one_of_strings([:normal, :high]) | ||
end | ||
|
||
defp service() do | ||
one_of_strings([:apns, :fcm]) | ||
end | ||
|
||
defp mode() do | ||
one_of_strings([:prod, :dev]) | ||
end | ||
|
||
defp data() do | ||
StreamData.map_of(StreamData.string(:ascii), StreamData.string(:ascii)) | ||
end | ||
|
||
defp one_of_strings(list_of_atoms) do | ||
StreamData.map(StreamData.one_of(list_of_atoms), &Kernel.to_string/1) | ||
end | ||
end |