Skip to content

Commit

Permalink
Adds syntax support for unicast GCM messages
Browse files Browse the repository at this point in the history
  • Loading branch information
howleysv committed Jan 25, 2016
1 parent 0774ad4 commit ebf55c1
Show file tree
Hide file tree
Showing 2 changed files with 65 additions and 24 deletions.
20 changes: 15 additions & 5 deletions lib/gcm.ex
Original file line number Diff line number Diff line change
Expand Up @@ -15,11 +15,13 @@ defmodule GCM do
"""
alias HTTPoison.Response

@base_url "https://android.googleapis.com/gcm"
@base_url "https://gcm-http.googleapis.com/gcm"

@doc """
Push a notification to a list of `registration_ids` using the `api_key` as authorization
Push a notification to a list of `registration_ids` or a single `registration_id`
using the `api_key` as authorization.
```
iex> GCM.push(api_key, ["registration_id1", "registration_id2"])
{:ok,
%{body: "...",
Expand All @@ -28,10 +30,18 @@ defmodule GCM do
{"Vary", "Accept-Encoding"}, {"Transfer-Encoding", "chunked"}],
invalid_registration_ids: [], not_registered_ids: [], status_code: 200,
success: 2}}
```
"""
@spec push(binary, [binary], map | [Keyword]) :: { :ok, map } | { :error, term }
def push(api_key, registration_ids, options \\ %{}) do
body = %{ registration_ids: registration_ids }
@spec push(String.t, String.t | [String.t], Map.t | Keyword.t) :: { :ok, Map.t } | { :error, term }
def push(api_key, registration_ids, options \\ %{})
def push(api_key, registration_id, options) when is_binary(registration_id) do
push(api_key, [registration_id], options)
end
def push(api_key, registration_ids, options) do
body = case registration_ids do
[id] -> %{ to: id }
ids -> %{ registration_ids: ids }
end
|> Dict.merge(options)
|> Poison.encode!

Expand Down
69 changes: 50 additions & 19 deletions test/gcm_test.exs
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ defmodule GCMTest do
:ok
end

test "push notification to GCM with a 200 response" do
test "push multicast notification to GCM with a 200 response" do
registration_ids = ["reg1", "reg2"]
options = %{ data: %{ alert: "Push!" } }
req_body = "req_body"
Expand All @@ -24,7 +24,7 @@ defmodule GCMTest do

expect(Poison, :encode!, [%{ registration_ids: registration_ids, data: %{ alert: "Push!" } }], req_body)
expect(Poison, :decode!, 1, resp_body)
expect(HTTPoison, :post, ["https://android.googleapis.com/gcm/send", req_body, [{"Authorization", "key=api_key"}, {"Content-Type", "application/json"}, {"Accept", "application/json"}]], { :ok, http_response })
expect(HTTPoison, :post, ["https://gcm-http.googleapis.com/gcm/send", req_body, [{"Authorization", "key=api_key"}, {"Content-Type", "application/json"}, {"Accept", "application/json"}]], { :ok, http_response })

assert push("api_key", registration_ids, options) ==
{ :ok, %{ canonical_ids: [],
Expand All @@ -39,8 +39,39 @@ defmodule GCMTest do
assert validate [Poison, HTTPoison]
end

test "push unicast notification to GCM with a 200 response" do
registration_id = "reg1"
options = %{ data: %{ alert: "Push!" } }
req_body = "req_body"
original_resp_body = "original"
headers = []
http_response = %HTTPoison.Response{ status_code: 200,
body: original_resp_body,
headers: headers}
resp_body = %{ "canonical_ids" => 0,
"failure" => 0,
"success" => 1,
"results" => [%{ "error" => "NotRegistered" }] }

expect(Poison, :encode!, [%{ to: registration_id, data: %{ alert: "Push!" } }], req_body)
expect(Poison, :decode!, 1, resp_body)
expect(HTTPoison, :post, ["https://gcm-http.googleapis.com/gcm/send", req_body, [{"Authorization", "key=api_key"}, {"Content-Type", "application/json"}, {"Accept", "application/json"}]], { :ok, http_response })

assert push("api_key", registration_id, options) ==
{ :ok, %{ canonical_ids: [],
not_registered_ids: [],
invalid_registration_ids: [],
success: 1,
failure: 0,
status_code: 200,
body: original_resp_body,
headers: headers } }

assert validate [Poison, HTTPoison]
end

test "push notification to GCM with NotRegistered" do
registration_ids = ["reg1"]
registration_id = "reg1"
options = %{ data: %{ alert: "Push!" } }
req_body = "req_body"
resp_body = %{ "canonical_ids" => 0,
Expand All @@ -54,11 +85,11 @@ defmodule GCMTest do
body: original_resp_body,
headers: headers}

expect(Poison, :encode!, [%{ registration_ids: registration_ids, data: %{ alert: "Push!" } }], req_body)
expect(Poison, :encode!, [%{ to: registration_id, data: %{ alert: "Push!" } }], req_body)
expect(Poison, :decode!, [original_resp_body], resp_body)
expect(HTTPoison, :post, ["https://android.googleapis.com/gcm/send", req_body, [{"Authorization", "key=api_key"}, {"Content-Type", "application/json"}, {"Accept", "application/json"}]], { :ok, http_response })
expect(HTTPoison, :post, ["https://gcm-http.googleapis.com/gcm/send", req_body, [{"Authorization", "key=api_key"}, {"Content-Type", "application/json"}, {"Accept", "application/json"}]], { :ok, http_response })

assert push("api_key", registration_ids, options) ==
assert push("api_key", registration_id, options) ==
{ :ok, %{ canonical_ids: [],
not_registered_ids: ["reg1"],
invalid_registration_ids: [],
Expand All @@ -72,7 +103,7 @@ defmodule GCMTest do
end

test "push notification to GCM with InvalidRegistration" do
registration_ids = ["reg1"]
registration_id = "reg1"
options = %{ data: %{ alert: "Push!" } }
req_body = "req_body"
resp_body = %{ "canonical_ids" => 0,
Expand All @@ -86,11 +117,11 @@ defmodule GCMTest do
body: original_resp_body,
headers: headers}

expect(Poison, :encode!, [%{ registration_ids: registration_ids, data: %{ alert: "Push!" } }], req_body)
expect(Poison, :encode!, [%{ to: registration_id, data: %{ alert: "Push!" } }], req_body)
expect(Poison, :decode!, [original_resp_body], resp_body)
expect(HTTPoison, :post, ["https://android.googleapis.com/gcm/send", req_body, [{"Authorization", "key=api_key"}, {"Content-Type", "application/json"}, {"Accept", "application/json"}]], { :ok, http_response })
expect(HTTPoison, :post, ["https://gcm-http.googleapis.com/gcm/send", req_body, [{"Authorization", "key=api_key"}, {"Content-Type", "application/json"}, {"Accept", "application/json"}]], { :ok, http_response })

assert push("api_key", registration_ids, options) ==
assert push("api_key", registration_id, options) ==
{ :ok, %{ canonical_ids: [],
not_registered_ids: [],
invalid_registration_ids: ["reg1"],
Expand All @@ -104,7 +135,7 @@ defmodule GCMTest do
end

test "push notification to GCM with canonical ids" do
registration_ids = ["reg1"]
registration_id = "reg1"
options = %{ data: %{ alert: "Push!" } }
req_body = "req_body"
resp_body = %{ "canonical_ids" => 1,
Expand All @@ -118,11 +149,11 @@ defmodule GCMTest do
body: original_resp_body,
headers: headers}

expect(Poison, :encode!, [%{ registration_ids: registration_ids, data: %{ alert: "Push!" } }], req_body)
expect(Poison, :encode!, [%{ to: registration_id, data: %{ alert: "Push!" } }], req_body)
expect(Poison, :decode!, [original_resp_body], resp_body)
expect(HTTPoison, :post, ["https://android.googleapis.com/gcm/send", req_body, [{"Authorization", "key=api_key"}, {"Content-Type", "application/json"}, {"Accept", "application/json"}]], { :ok, http_response })
expect(HTTPoison, :post, ["https://gcm-http.googleapis.com/gcm/send", req_body, [{"Authorization", "key=api_key"}, {"Content-Type", "application/json"}, {"Accept", "application/json"}]], { :ok, http_response })

assert push("api_key", registration_ids, options) ==
assert push("api_key", registration_id, options) ==
{ :ok, %{ canonical_ids: [%{ old: "reg1", new: "newreg1" }],
not_registered_ids: [],
invalid_registration_ids: [],
Expand Down Expand Up @@ -155,7 +186,7 @@ defmodule GCMTest do

expect(Poison, :encode!, [%{ registration_ids: registration_ids, data: %{ alert: "Push!" } }], req_body)
expect(Poison, :decode!, [original_resp_body], resp_body)
expect(HTTPoison, :post, ["https://android.googleapis.com/gcm/send", req_body, [{"Authorization", "key=api_key"}, {"Content-Type", "application/json"}, {"Accept", "application/json"}]], { :ok, http_response })
expect(HTTPoison, :post, ["https://gcm-http.googleapis.com/gcm/send", req_body, [{"Authorization", "key=api_key"}, {"Content-Type", "application/json"}, {"Accept", "application/json"}]], { :ok, http_response })

assert push("api_key", registration_ids, options) ==
{ :ok, %{ canonical_ids: [%{ old: "old_reg", new: "new_reg" }],
Expand All @@ -176,7 +207,7 @@ defmodule GCMTest do
http_response = %HTTPoison.Response{status_code: 400, body: "{}"}

expect(Poison, :encode!, [%{ registration_ids: registration_ids }], req_body)
expect(HTTPoison, :post, ["https://android.googleapis.com/gcm/send", req_body, [{"Authorization", "key=api_key"}, {"Content-Type", "application/json"}, {"Accept", "application/json"}]], { :ok, http_response })
expect(HTTPoison, :post, ["https://gcm-http.googleapis.com/gcm/send", req_body, [{"Authorization", "key=api_key"}, {"Content-Type", "application/json"}, {"Accept", "application/json"}]], { :ok, http_response })

assert push("api_key", registration_ids) == { :error, :bad_request }

Expand All @@ -189,7 +220,7 @@ defmodule GCMTest do
http_response = %HTTPoison.Response{status_code: 401, body: "{}"}

expect(Poison, :encode!, [%{ registration_ids: registration_ids }], req_body)
expect(HTTPoison, :post, ["https://android.googleapis.com/gcm/send", req_body, [{"Authorization", "key=api_key"}, {"Content-Type", "application/json"}, {"Accept", "application/json"}]], { :ok, http_response })
expect(HTTPoison, :post, ["https://gcm-http.googleapis.com/gcm/send", req_body, [{"Authorization", "key=api_key"}, {"Content-Type", "application/json"}, {"Accept", "application/json"}]], { :ok, http_response })

assert push("api_key", registration_ids) == { :error, :unauthorized }

Expand All @@ -202,7 +233,7 @@ defmodule GCMTest do
http_response = %HTTPoison.Response{status_code: 503, body: "{}"}

expect(Poison, :encode!, [%{ registration_ids: registration_ids }], req_body)
expect(HTTPoison, :post, ["https://android.googleapis.com/gcm/send", req_body, [{"Authorization", "key=api_key"}, {"Content-Type", "application/json"}, {"Accept", "application/json"}]], { :ok, http_response })
expect(HTTPoison, :post, ["https://gcm-http.googleapis.com/gcm/send", req_body, [{"Authorization", "key=api_key"}, {"Content-Type", "application/json"}, {"Accept", "application/json"}]], { :ok, http_response })

assert push("api_key", registration_ids) == { :error, :service_unavaiable }

Expand All @@ -215,7 +246,7 @@ defmodule GCMTest do
http_response = %HTTPoison.Response{status_code: 504, body: "{}"}

expect(Poison, :encode!, [%{ registration_ids: registration_ids }], req_body)
expect(HTTPoison, :post, ["https://android.googleapis.com/gcm/send", req_body, [{"Authorization", "key=api_key"}, {"Content-Type", "application/json"}, {"Accept", "application/json"}]], { :ok, http_response })
expect(HTTPoison, :post, ["https://gcm-http.googleapis.com/gcm/send", req_body, [{"Authorization", "key=api_key"}, {"Content-Type", "application/json"}, {"Accept", "application/json"}]], { :ok, http_response })

assert push("api_key", registration_ids) == { :error, :server_error }

Expand Down

0 comments on commit ebf55c1

Please sign in to comment.