diff --git a/lib/structs/field_content.ex b/lib/structs/field_content.ex
index ca7fb89..61e16c1 100644
--- a/lib/structs/field_content.ex
+++ b/lib/structs/field_content.ex
@@ -35,6 +35,11 @@ defmodule ExPass.Structs.FieldContent do
* "PKDateStyleMedium"
* "PKDateStyleLong"
* "PKDateStyleFull"
+
+ - `ignores_time_zone`: A Boolean value that controls the time zone for the time and date to display in the field.
+ The default value is false, which displays the time and date using the current device's time zone.
+ If set to true, the time and date appear in the time zone associated with the date and time of value.
+ This key doesn't affect the pass relevance calculation.
"""
use TypedStruct
@@ -101,13 +106,14 @@ defmodule ExPass.Structs.FieldContent do
field :currency_code, String.t(), default: nil
field :data_detector_types, data_detector_types(), default: nil
field :date_style, date_style(), default: nil
+ field :ignores_time_zone, boolean(), default: nil
end
@doc """
Creates a new FieldContent struct.
This function initializes a new FieldContent struct with the given attributes.
- It validates the `attributed_value`, `change_message`, `currency_code`, `data_detector_types`, and `date_style`.
+ It validates the `attributed_value`, `change_message`, `currency_code`, `data_detector_types`, `date_style`, and `ignores_time_zone`.
## Parameters
@@ -124,22 +130,22 @@ defmodule ExPass.Structs.FieldContent do
## Examples
iex> FieldContent.new(%{attributed_value: "Hello, World!"})
- %FieldContent{attributed_value: "Hello, World!", change_message: nil, currency_code: nil, data_detector_types: nil, date_style: nil}
+ %FieldContent{attributed_value: "Hello, World!", change_message: nil, currency_code: nil, data_detector_types: nil, date_style: nil, ignores_time_zone: nil}
- iex> FieldContent.new(%{attributed_value: 42, data_detector_types: ["PKDataDetectorTypePhoneNumber"], date_style: "PKDateStyleShort"})
- %FieldContent{attributed_value: 42, change_message: nil, currency_code: nil, data_detector_types: ["PKDataDetectorTypePhoneNumber"], date_style: "PKDateStyleShort"}
+ iex> FieldContent.new(%{attributed_value: 42, data_detector_types: ["PKDataDetectorTypePhoneNumber"], date_style: "PKDateStyleShort", ignores_time_zone: true})
+ %FieldContent{attributed_value: 42, change_message: nil, currency_code: nil, data_detector_types: ["PKDataDetectorTypePhoneNumber"], date_style: "PKDateStyleShort", ignores_time_zone: true}
- iex> datetime = DateTime.utc_now()
- iex> field_content = FieldContent.new(%{attributed_value: datetime, currency_code: "USD", date_style: "PKDateStyleLong"})
- iex> %FieldContent{attributed_value: ^datetime, currency_code: "USD", date_style: "PKDateStyleLong"} = field_content
+ iex> datetime = ~U[2023-04-15 14:30:00Z]
+ iex> field_content = FieldContent.new(%{attributed_value: datetime, currency_code: "USD", date_style: "PKDateStyleLong", ignores_time_zone: true})
+ iex> %FieldContent{attributed_value: ^datetime, currency_code: "USD", date_style: "PKDateStyleLong", ignores_time_zone: true} = field_content
iex> field_content.change_message
nil
iex> FieldContent.new(%{attributed_value: "Click here", data_detector_types: ["PKDataDetectorTypeLink"], date_style: "PKDateStyleFull"})
- %FieldContent{attributed_value: "Click here", change_message: nil, currency_code: nil, data_detector_types: ["PKDataDetectorTypeLink"], date_style: "PKDateStyleFull"}
+ %FieldContent{attributed_value: "Click here", change_message: nil, currency_code: nil, data_detector_types: ["PKDataDetectorTypeLink"], date_style: "PKDateStyleFull", ignores_time_zone: nil}
- iex> FieldContent.new(%{attributed_value: "No detectors", data_detector_types: []})
- %FieldContent{attributed_value: "No detectors", change_message: nil, currency_code: nil, data_detector_types: [], date_style: nil}
+ iex> FieldContent.new(%{attributed_value: "No detectors", data_detector_types: [], change_message: "Updated to %@", ignores_time_zone: true})
+ %FieldContent{attributed_value: "No detectors", change_message: "Updated to %@", currency_code: nil, data_detector_types: [], date_style: nil, ignores_time_zone: true}
"""
@spec new(map()) :: %__MODULE__{}
def new(attrs \\ %{}) do
@@ -151,6 +157,7 @@ defmodule ExPass.Structs.FieldContent do
|> validate(:currency_code, &Validators.validate_currency_code/1)
|> validate(:data_detector_types, &Validators.validate_data_detector_types/1)
|> validate(:date_style, &Validators.validate_date_style/1)
+ |> validate(:ignores_time_zone, &Validators.validate_ignores_timezone/1)
struct!(__MODULE__, attrs)
end
@@ -186,6 +193,9 @@ defmodule ExPass.Structs.FieldContent do
:date_style ->
"Supported values are: PKDateStyleNone, PKDateStyleShort, PKDateStyleMedium, PKDateStyleLong, PKDateStyleFull"
+ :ignores_time_zone ->
+ "ignores_time_zone must be a boolean value (true or false)"
+
_ ->
""
end
diff --git a/lib/utils/validators.ex b/lib/utils/validators.ex
index 6e8dec7..d047f55 100644
--- a/lib/utils/validators.ex
+++ b/lib/utils/validators.ex
@@ -250,6 +250,36 @@ defmodule ExPass.Utils.Validators do
def validate_date_style(_), do: {:error, "date_style must be a string"}
+ @doc """
+ Validates the ignores_time_zone field.
+
+ The ignores_time_zone must be a boolean value.
+
+ ## Returns
+
+ * `:ok` if the value is a valid boolean or nil.
+ * `{:error, reason}` if the value is not valid, where reason is a string explaining the error.
+
+ ## Examples
+
+ iex> validate_ignores_timezone(true)
+ :ok
+
+ iex> validate_ignores_timezone(false)
+ :ok
+
+ iex> validate_ignores_timezone(nil)
+ :ok
+
+ iex> validate_ignores_timezone("true")
+ {:error, "ignores_time_zone must be a boolean"}
+
+ """
+ @spec validate_ignores_timezone(boolean() | nil) :: :ok | {:error, String.t()}
+ def validate_ignores_timezone(nil), do: :ok
+ def validate_ignores_timezone(value) when is_boolean(value), do: :ok
+ def validate_ignores_timezone(_), do: {:error, "ignores_time_zone must be a boolean"}
+
defp contains_unsupported_html_tags?(string) do
# Remove all valid anchor tags
string_without_anchors = String.replace(string, ~r{]*>.*?|]*/>}, "")
diff --git a/test/structs/field_content_test.exs b/test/structs/field_content_test.exs
index d9baa56..aaeb132 100644
--- a/test/structs/field_content_test.exs
+++ b/test/structs/field_content_test.exs
@@ -220,4 +220,33 @@ defmodule ExPass.Structs.FieldContentTest do
end
end
end
+
+ describe "ignores_time_zone" do
+ test "new/1 creates a valid FieldContent struct with ignores_time_zone set to true" do
+ result = FieldContent.new(%{ignores_time_zone: true})
+
+ assert %FieldContent{ignores_time_zone: true} = result
+ assert Jason.encode!(result) == ~s({"ignoresTimeZone":true})
+ end
+
+ test "new/1 creates a valid FieldContent struct with ignores_time_zone set to false" do
+ result = FieldContent.new(%{ignores_time_zone: false})
+
+ assert %FieldContent{ignores_time_zone: false} = result
+ assert Jason.encode!(result) == ~s({"ignoresTimeZone":false})
+ end
+
+ test "new/1 defaults to nil when ignores_time_zone is not provided" do
+ result = FieldContent.new(%{})
+
+ assert %FieldContent{ignores_time_zone: nil} = result
+ assert Jason.encode!(result) == ~s({})
+ end
+
+ test "new/1 raises ArgumentError when ignores_time_zone is not a boolean" do
+ assert_raise ArgumentError, ~r/ignores_time_zone must be a boolean/, fn ->
+ FieldContent.new(%{ignores_time_zone: "true"})
+ end
+ end
+ end
end