-
Notifications
You must be signed in to change notification settings - Fork 83
Expand file tree
/
Copy pathapi_case.ex
More file actions
131 lines (104 loc) · 4.04 KB
/
api_case.ex
File metadata and controls
131 lines (104 loc) · 4.04 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
defmodule CodeCorpsWeb.ApiCase do
@moduledoc """
This module defines the test case to be used by
tests that require setting up a connection, specificaly,
those working with the API endpoints.
It's basically a clone of CodeCorpsWeb.ConnCase, with some extras,
mainly authentication and proper headers, added.
If provided with a :resource_name option, it dynamically
generates higher level request helper methods
## Examples
use ApiCase, resource_name: :task
use ApiCase, resource_name: :comment
"""
import CodeCorps.Factories
use ExUnit.CaseTemplate
use Phoenix.ConnTest
using(opts) do
quote do
# Import conveniences for testing with connections
use Phoenix.ConnTest
alias CodeCorps.Repo
import Ecto
import Ecto.Changeset
import Ecto.Query
import CodeCorps.AuthenticationTestHelpers
import CodeCorpsWeb.Router.Helpers
import CodeCorps.Factories
import CodeCorps.TestHelpers
# The default endpoint for testing
@endpoint CodeCorpsWeb.Endpoint
CodeCorpsWeb.ApiCase.define_request_helper_methods(unquote(opts))
end
end
setup tags do
:ok = Ecto.Adapters.SQL.Sandbox.checkout(CodeCorps.Repo)
unless tags[:async] do
Ecto.Adapters.SQL.Sandbox.mode(CodeCorps.Repo, {:shared, self()})
end
conn =
%{build_conn() | host: "api."}
|> put_req_header("accept", "application/vnd.api+json")
|> put_req_header("content-type", "application/vnd.api+json")
{conn, current_user} = cond do
tags[:authenticated] ->
conn |> add_authentication_headers(tags[:authenticated])
true ->
{conn, nil}
end
{:ok, conn: conn, current_user: current_user}
end
defp add_authentication_headers(conn, true) do
user = insert(:user)
conn = conn |> CodeCorps.AuthenticationTestHelpers.authenticate(user)
{conn, user}
end
defp add_authentication_headers(conn, :admin) do
admin = insert(:user, admin: true)
conn = conn |> CodeCorps.AuthenticationTestHelpers.authenticate(admin)
{conn, admin}
end
defmacro define_request_helper_methods(resource_name: resource_name), do: do_add_request_helper_methods(resource_name)
defmacro define_request_helper_methods(_), do: nil
defp do_add_request_helper_methods(resource_name) do
quote do
defp factory_name, do: unquote(resource_name)
defp path_helper_method, do: "#{unquote(resource_name)}_path" |> String.to_atom
defp default_record, do: insert(unquote(resource_name))
defp path_for(conn, action, resource_or_id) do
apply(CodeCorpsWeb.Router.Helpers, path_helper_method(), [conn, action, resource_or_id])
end
defp path_for(conn, action) do
apply(CodeCorpsWeb.Router.Helpers, path_helper_method(), [conn, action])
end
def request_index(conn) do
path = conn |> path_for(:index)
conn |> get(path)
end
def request_show(conn, :not_found), do: conn |> request_show(-1)
def request_show(conn, resource_or_id) do
path = conn |> path_for(:show, resource_or_id)
conn |> get(path)
end
def request_create(conn, attrs \\ %{}) do
path = conn |> path_for(:create)
payload = CodeCorps.JsonAPIHelpers.build_json_payload(attrs)
conn |> post(path, payload)
end
def request_update(conn), do: request_update(conn, %{})
def request_update(conn, :not_found), do: request_update(conn, -1, %{})
def request_update(conn, attrs), do: request_update(conn, default_record(), attrs)
def request_update(conn, resource_or_id, attrs) do
payload = CodeCorps.JsonAPIHelpers.build_json_payload(attrs)
path = conn |> path_for(:update, resource_or_id)
conn |> put(path, payload)
end
def request_delete(conn), do: request_delete(conn, default_record())
def request_delete(conn, :not_found), do: request_delete(conn, -1)
def request_delete(conn, resource_or_id) do
path = conn |> path_for(:delete, resource_or_id)
conn |> delete(path)
end
end
end
end