Skip to content

Commit

Permalink
Make JSON library an optional dependency.
Browse files Browse the repository at this point in the history
Use `Jason` by default.
  • Loading branch information
linjunpop committed Jul 31, 2018
1 parent 9be3b03 commit c453080
Show file tree
Hide file tree
Showing 7 changed files with 102 additions and 32 deletions.
3 changes: 3 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,9 @@

## master

* Make JSON library an optional dependency,
[Jason](https://github.com/michalmuskala/jason) is recommended.

## v0.11.0

* Allow `Poison ~> 4.0` to be used. Thanks @ericentin.
Expand Down
12 changes: 11 additions & 1 deletion docs/Getting Started.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,8 @@ Simply add receipt_verifier to your list of dependencies in `mix.exs`:
```elixir
def deps do
[
{:receipt_verifier, "~> 0.11.0"}
{:receipt_verifier, "~> 0.11.0"},
{:jason, "~> 1.0"} # or {:poison, "~> 4.0"}
]
end
```
Expand Down Expand Up @@ -59,3 +60,12 @@ iex> ReceiptVerifier.verify(BASE64_ENCODED_RECEIPT_DATA, env: :production)
version_external_identifier: 0}, base64_latest_app_receipt: nil,
environment: "Sandbox", latest_iap_receipts: [], pending_renewal_receipts: []}
```

## JSON Encoder

By default, `ReceiptVerifier` use `Jason` to encode JSON, if you want to use `Poison`,
you can configure `:receipt_verifier` application with:

```elixir
config :receipt_verifier, :json_library, Poison
```
5 changes: 4 additions & 1 deletion lib/receipt_verifier/client.ex
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,9 @@ defmodule ReceiptVerifier.Client do
@moduledoc false

alias ReceiptVerifier.Error
alias ReceiptVerifier.JSON

require JSON

@endpoints [
production: 'https://buy.itunes.apple.com/verifyReceipt',
Expand All @@ -14,7 +17,7 @@ defmodule ReceiptVerifier.Client do
@spec request(String.t(), map) :: {:ok, map} | {:error, any}
def request(receipt, opts) do
with {:ok, {{_, 200, _}, _, body}} <- do_request(receipt, opts),
{:ok, json} <- Poison.decode(body) do
{:ok, json} <- JSON.decode(body) do
{:ok, json}
else
{:ok, {{_, status_code, msg}, _, _body}} ->
Expand Down
39 changes: 39 additions & 0 deletions lib/receipt_verifier/json.ex
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
defmodule ReceiptVerifier.JSON do
@moduledoc """
The module act as an adapter to JSON library
By default, it use `Jason` to encode JSON, if you want to use `Poison`,
you can configure `:receipt_verifier` application with:
```elixir
config :receipt_verifier, :json_library, Poison
```
"""

json_lib =
case Application.get_env(:receipt_verifier, :json_library, Jason) do
lib when lib in [Jason, Poison] ->
lib

other ->
IO.warn("""
You has set the JSON Library to `#{other}`, which might not work as expected.
Currently, only `Jason` and `Poison` are supported,
you can config it with:
config :receipt_verifier, :json_library, Jason
""")

other
end

@json_lib json_lib

@doc false
defmacro decode(value) do
quote do
unquote(@json_lib).decode(unquote(value))
end
end
end
9 changes: 5 additions & 4 deletions mix.exs
Original file line number Diff line number Diff line change
Expand Up @@ -35,12 +35,13 @@ defmodule ReceiptVerifier.Mixfile do

defp deps do
[
{:poison, "~> 2.0 or ~> 3.0 or ~> 4.0"},
{:poison, "~> 3.0", only: [:dev, :test, :docs]},
{:jason, "~> 1.0", only: [:dev, :test]},
{:dialyxir, "~> 0.5", only: :dev},
{:exvcr, "~> 0.8", only: :test},
{:credo, "~> 0.7", only: [:dev, :test]},
{:inch_ex, "~> 0.5", only: :docs},
{:ex_doc, "~> 0.15", only: [:dev, :docs]}
{:credo, "~> 0.10", only: [:dev, :test]},
{:inch_ex, "~> 1.0", only: [:dev, :test, :docs]},
{:ex_doc, "~> 0.19", only: [:dev, :docs]}
]
end

Expand Down
35 changes: 17 additions & 18 deletions mix.lock
Original file line number Diff line number Diff line change
@@ -1,19 +1,18 @@
%{"bunt": {:hex, :bunt, "0.2.0", "951c6e801e8b1d2cbe58ebbd3e616a869061ddadcc4863d0a2182541acae9a38", [:mix], [], "hexpm"},
"certifi": {:hex, :certifi, "0.7.0", "861a57f3808f7eb0c2d1802afeaae0fa5de813b0df0979153cbafcd853ababaf", [:rebar3], []},
"credo": {:hex, :credo, "0.8.4", "4e50acac058cf6292d6066e5b0d03da5e1483702e1ccde39abba385c9f03ead4", [:mix], [{:bunt, "~> 0.2.0", [hex: :bunt, repo: "hexpm", optional: false]}], "hexpm"},
"dialyxir": {:hex, :dialyxir, "0.5.0", "5bc543f9c28ecd51b99cc1a685a3c2a1a93216990347f259406a910cf048d1d7", [:mix], [], "hexpm"},
"earmark": {:hex, :earmark, "1.2.2", "f718159d6b65068e8daeef709ccddae5f7fdc770707d82e7d126f584cd925b74", [:mix], [], "hexpm"},
"ex_doc": {:hex, :ex_doc, "0.16.2", "3b3e210ebcd85a7c76b4e73f85c5640c011d2a0b2f06dcdf5acdb2ae904e5084", [:mix], [{:earmark, "~> 1.1", [hex: :earmark, repo: "hexpm", optional: false]}], "hexpm"},
"exactor": {:hex, :exactor, "2.2.3", "a6972f43bb6160afeb73e1d8ab45ba604cd0ac8b5244c557093f6e92ce582786", [:mix], [], "hexpm"},
"exjsx": {:hex, :exjsx, "3.2.1", "1bc5bf1e4fd249104178f0885030bcd75a4526f4d2a1e976f4b428d347614f0f", [:mix], [{:jsx, "~> 2.8.0", [hex: :jsx, repo: "hexpm", optional: false]}], "hexpm"},
"exvcr": {:hex, :exvcr, "0.8.11", "76d6f3f93cb764ccb34abca3f54ecdd980a178f908d175e6a326535e0f18e863", [:mix], [{:exactor, "~> 2.2", [hex: :exactor, repo: "hexpm", optional: false]}, {:exjsx, "~> 3.2", [hex: :exjsx, repo: "hexpm", optional: false]}, {:httpoison, "~> 0.11", [hex: :httpoison, repo: "hexpm", optional: true]}, {:httpotion, "~> 3.0", [hex: :httpotion, repo: "hexpm", optional: true]}, {:ibrowse, "~> 4.2.2", [hex: :ibrowse, repo: "hexpm", optional: true]}, {:meck, "~> 0.8.3", [hex: :meck, repo: "hexpm", optional: false]}], "hexpm"},
"hackney": {:hex, :hackney, "1.6.3", "d489d7ca2d4323e307bedc4bfe684323a7bf773ecfd77938f3ee8074e488e140", [:mix, :rebar3], [{:certifi, "0.7.0", [hex: :certifi, optional: false]}, {:idna, "1.2.0", [hex: :idna, optional: false]}, {:metrics, "1.0.1", [hex: :metrics, optional: false]}, {:mimerl, "1.0.2", [hex: :mimerl, optional: false]}, {:ssl_verify_fun, "1.1.1", [hex: :ssl_verify_fun, optional: false]}]},
"httpoison": {:hex, :httpoison, "0.9.0", "68187a2daddfabbe7ca8f7d75ef227f89f0e1507f7eecb67e4536b3c516faddb", [:mix], [{:hackney, "~> 1.6.0", [hex: :hackney, optional: false]}]},
"idna": {:hex, :idna, "1.2.0", "ac62ee99da068f43c50dc69acf700e03a62a348360126260e87f2b54eced86b2", [:rebar3], []},
"inch_ex": {:hex, :inch_ex, "0.5.6", "418357418a553baa6d04eccd1b44171936817db61f4c0840112b420b8e378e67", [:mix], [{:poison, "~> 1.5 or ~> 2.0 or ~> 3.0", [hex: :poison, repo: "hexpm", optional: false]}], "hexpm"},
"jsx": {:hex, :jsx, "2.8.2", "7acc7d785b5abe8a6e9adbde926a24e481f29956dd8b4df49e3e4e7bcc92a018", [:mix, :rebar3], [], "hexpm"},
"meck": {:hex, :meck, "0.8.7", "ebad16ca23f685b07aed3bc011efff65fbaf28881a8adf925428ef5472d390ee", [:rebar3], [], "hexpm"},
"metrics": {:hex, :metrics, "1.0.1", "25f094dea2cda98213cecc3aeff09e940299d950904393b2a29d191c346a8486", [:rebar3], []},
"mimerl": {:hex, :mimerl, "1.0.2", "993f9b0e084083405ed8252b99460c4f0563e41729ab42d9074fd5e52439be88", [:rebar3], []},
%{
"bunt": {:hex, :bunt, "0.2.0", "951c6e801e8b1d2cbe58ebbd3e616a869061ddadcc4863d0a2182541acae9a38", [:mix], [], "hexpm"},
"credo": {:hex, :credo, "0.10.0", "66234a95effaf9067edb19fc5d0cd5c6b461ad841baac42467afed96c78e5e9e", [:mix], [{:bunt, "~> 0.2.0", [hex: :bunt, repo: "hexpm", optional: false]}, {:jason, "~> 1.0", [hex: :jason, repo: "hexpm", optional: false]}], "hexpm"},
"dialyxir": {:hex, :dialyxir, "0.5.1", "b331b091720fd93e878137add264bac4f644e1ddae07a70bf7062c7862c4b952", [:mix], [], "hexpm"},
"earmark": {:hex, :earmark, "1.2.5", "4d21980d5d2862a2e13ec3c49ad9ad783ffc7ca5769cf6ff891a4553fbaae761", [:mix], [], "hexpm"},
"ex_doc": {:hex, :ex_doc, "0.19.0", "e22b6434373b4870ea77b24df069dbac7002c1f483615e9ebfc0c37497e1c75c", [:mix], [{:earmark, "~> 1.1", [hex: :earmark, repo: "hexpm", optional: false]}, {:makeup_elixir, "~> 0.7", [hex: :makeup_elixir, repo: "hexpm", optional: false]}], "hexpm"},
"exactor": {:hex, :exactor, "2.2.4", "5efb4ddeb2c48d9a1d7c9b465a6fffdd82300eb9618ece5d34c3334d5d7245b1", [:mix], [], "hexpm"},
"exjsx": {:hex, :exjsx, "4.0.0", "60548841e0212df401e38e63c0078ec57b33e7ea49b032c796ccad8cde794b5c", [:mix], [{:jsx, "~> 2.8.0", [hex: :jsx, repo: "hexpm", optional: false]}], "hexpm"},
"exvcr": {:hex, :exvcr, "0.10.2", "a66a0fa86d03153e5c21e38b1320d10b537038d7bc7b10dcc1ab7f0343569822", [:mix], [{:exactor, "~> 2.2", [hex: :exactor, repo: "hexpm", optional: false]}, {:exjsx, "~> 4.0", [hex: :exjsx, repo: "hexpm", optional: false]}, {:httpoison, "~> 1.0", [hex: :httpoison, repo: "hexpm", optional: true]}, {:httpotion, "~> 3.1", [hex: :httpotion, repo: "hexpm", optional: true]}, {:ibrowse, "~> 4.4", [hex: :ibrowse, repo: "hexpm", optional: true]}, {:meck, "~> 0.8", [hex: :meck, repo: "hexpm", optional: false]}], "hexpm"},
"inch_ex": {:hex, :inch_ex, "1.0.0", "18496a900ca4b7542a1ff1159e7f8be6c2012b74ca55ac70de5e805f14cdf939", [:mix], [{:poison, "~> 1.5 or ~> 2.0 or ~> 3.0", [hex: :poison, repo: "hexpm", optional: false]}], "hexpm"},
"jason": {:hex, :jason, "1.1.1", "d3ccb840dfb06f2f90a6d335b536dd074db748b3e7f5b11ab61d239506585eb2", [:mix], [{:decimal, "~> 1.0", [hex: :decimal, repo: "hexpm", optional: true]}], "hexpm"},
"jsx": {:hex, :jsx, "2.8.3", "a05252d381885240744d955fbe3cf810504eb2567164824e19303ea59eef62cf", [:mix, :rebar3], [], "hexpm"},
"makeup": {:hex, :makeup, "0.5.1", "966c5c2296da272d42f1de178c1d135e432662eca795d6dc12e5e8787514edf7", [:mix], [{:nimble_parsec, "~> 0.2.2", [hex: :nimble_parsec, repo: "hexpm", optional: false]}], "hexpm"},
"makeup_elixir": {:hex, :makeup_elixir, "0.8.0", "1204a2f5b4f181775a0e456154830524cf2207cf4f9112215c05e0b76e4eca8b", [:mix], [{:makeup, "~> 0.5.0", [hex: :makeup, repo: "hexpm", optional: false]}, {:nimble_parsec, "~> 0.2.2", [hex: :nimble_parsec, repo: "hexpm", optional: false]}], "hexpm"},
"meck": {:hex, :meck, "0.8.11", "2c39e15ec87d847da6cf69b4a1c4af3fd850ae2a272e719e0e8751a7fe54771f", [:rebar3], [], "hexpm"},
"nimble_parsec": {:hex, :nimble_parsec, "0.2.2", "d526b23bdceb04c7ad15b33c57c4526bf5f50aaa70c7c141b4b4624555c68259", [:mix], [], "hexpm"},
"poison": {:hex, :poison, "3.1.0", "d9eb636610e096f86f25d9a46f35a9facac35609a7591b3be3326e99a0484665", [:mix], [], "hexpm"},
"ssl_verify_fun": {:hex, :ssl_verify_fun, "1.1.1", "28a4d65b7f59893bc2c7de786dec1e1555bd742d336043fe644ae956c3497fbe", [:make, :rebar], []}}
}
31 changes: 23 additions & 8 deletions test/receipt_verifier_test.exs
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ defmodule ReceiptVerifierTest do

alias ReceiptVerifier.ResponseData

setup_all do
setup do
ExVCR.Config.cassette_library_dir("test/fixtures/vcr_cassettes")
:ok
end
Expand Down Expand Up @@ -59,7 +59,9 @@ defmodule ReceiptVerifierTest do
pending_renewal_receipt = List.last(pending_renewal_receipts)

assert false == pending_renewal_receipt.is_in_billing_retry_period
assert "com.sumiapp.GridDiary.pro_subscription" == pending_renewal_receipt.auto_renew_product_id

assert "com.sumiapp.GridDiary.pro_subscription" ==
pending_renewal_receipt.auto_renew_product_id
end
end
end
Expand All @@ -69,7 +71,12 @@ defmodule ReceiptVerifierTest do
use_cassette "exclude_old_transactions_false" do
base64_receipt = read_receipt_file("griddiary_production")

{:ok, result} = ReceiptVerifier.verify(base64_receipt, exclude_old_transactions: false, password: "sample-secret")
{:ok, result} =
ReceiptVerifier.verify(
base64_receipt,
exclude_old_transactions: false,
password: "sample-secret"
)

assert 3 == length(result.latest_iap_receipts)
end
Expand All @@ -79,7 +86,12 @@ defmodule ReceiptVerifierTest do
use_cassette "exclude_old_transactions" do
base64_receipt = read_receipt_file("griddiary_production")

{:ok, result} = ReceiptVerifier.verify(base64_receipt, exclude_old_transactions: true, password: "sample-secret")
{:ok, result} =
ReceiptVerifier.verify(
base64_receipt,
exclude_old_transactions: true,
password: "sample-secret"
)

assert 1 == length(result.latest_iap_receipts)
end
Expand All @@ -91,7 +103,8 @@ defmodule ReceiptVerifierTest do
use_cassette "invalid_receipt" do
base64_receipt = "foobar"

{:error, %ReceiptVerifier.Error{code: code, message: msg}} = ReceiptVerifier.verify(base64_receipt)
{:error, %ReceiptVerifier.Error{code: code, message: msg}} =
ReceiptVerifier.verify(base64_receipt)

assert 21002 == code
assert "The data in the receipt-data property was malformed or missing." == msg
Expand All @@ -104,7 +117,8 @@ defmodule ReceiptVerifierTest do
use_cassette "production_receipt_to_sandbox" do
base64_receipt = read_receipt_file("griddiary_production")

{:error, %ReceiptVerifier.Error{} = err} = ReceiptVerifier.verify(base64_receipt, env: :sandbox)
{:error, %ReceiptVerifier.Error{} = err} =
ReceiptVerifier.verify(base64_receipt, env: :sandbox)

assert 21008 == err.code
end
Expand All @@ -114,7 +128,8 @@ defmodule ReceiptVerifierTest do
use_cassette "sandbox_receipt_to_production" do
base64_receipt = read_receipt_file("receipt")

{:error, %ReceiptVerifier.Error{} = err} = ReceiptVerifier.verify(base64_receipt, env: :production)
{:error, %ReceiptVerifier.Error{} = err} =
ReceiptVerifier.verify(base64_receipt, env: :production)

assert 21007 == err.code
end
Expand All @@ -135,7 +150,7 @@ defmodule ReceiptVerifierTest do

defp read_receipt_file(filename) do
"test/fixtures/receipts/#{filename}"
|> File.read!
|> File.read!()
|> String.replace("\n", "")
end
end

0 comments on commit c453080

Please sign in to comment.