Auto-indexing service and GraphQL API for AT Protocol Records
quickslice.slices.network/
atproto
gleam
graphql
1import gleam/http
2import gleam/json
3import gleam/string
4import gleeunit/should
5import handlers/oauth/register
6import test_helpers
7import wisp
8import wisp/simulate
9
10pub fn register_valid_client_test() {
11 let assert Ok(exec) = test_helpers.create_test_db()
12 let assert Ok(_) = test_helpers.create_all_tables(exec)
13
14 let body =
15 json.object([
16 #("client_name", json.string("Test Client")),
17 #(
18 "redirect_uris",
19 json.array([json.string("https://example.com/callback")], fn(x) { x }),
20 ),
21 ])
22 |> json.to_string
23
24 let req =
25 simulate.request(http.Post, "/oauth/register")
26 |> simulate.string_body(body)
27 |> simulate.header("content-type", "application/json")
28
29 let response = register.handle(req, exec)
30
31 response.status |> should.equal(201)
32
33 case response.body {
34 wisp.Text(response_body) -> {
35 response_body |> string.contains("client_id") |> should.be_true
36 response_body |> string.contains("Test Client") |> should.be_true
37 }
38 _ -> should.fail()
39 }
40}
41
42pub fn register_missing_redirect_uris_test() {
43 let assert Ok(exec) = test_helpers.create_test_db()
44 let assert Ok(_) = test_helpers.create_all_tables(exec)
45
46 let body =
47 json.object([
48 #("client_name", json.string("Test Client")),
49 #("redirect_uris", json.array([], fn(x) { x })),
50 ])
51 |> json.to_string
52
53 let req =
54 simulate.request(http.Post, "/oauth/register")
55 |> simulate.string_body(body)
56 |> simulate.header("content-type", "application/json")
57
58 let response = register.handle(req, exec)
59
60 response.status |> should.equal(400)
61}
62
63pub fn register_http_non_localhost_redirect_uri_rejected_test() {
64 let assert Ok(exec) = test_helpers.create_test_db()
65 let assert Ok(_) = test_helpers.create_all_tables(exec)
66
67 // http:// on a non-localhost domain should be rejected
68 let body =
69 json.object([
70 #("client_name", json.string("Test Client")),
71 #(
72 "redirect_uris",
73 json.array([json.string("http://example.com/callback")], fn(x) { x }),
74 ),
75 ])
76 |> json.to_string
77
78 let req =
79 simulate.request(http.Post, "/oauth/register")
80 |> simulate.string_body(body)
81 |> simulate.header("content-type", "application/json")
82
83 let response = register.handle(req, exec)
84
85 // Should return 400 Bad Request because HTTP is only allowed for localhost
86 response.status |> should.equal(400)
87
88 case response.body {
89 wisp.Text(response_body) -> {
90 response_body |> string.contains("redirect") |> should.be_true
91 }
92 _ -> should.fail()
93 }
94}
95
96pub fn register_http_localhost_redirect_uri_allowed_test() {
97 let assert Ok(exec) = test_helpers.create_test_db()
98 let assert Ok(_) = test_helpers.create_all_tables(exec)
99
100 // http://localhost should be allowed
101 let body =
102 json.object([
103 #("client_name", json.string("Test Client")),
104 #(
105 "redirect_uris",
106 json.array([json.string("http://localhost:3000/callback")], fn(x) { x }),
107 ),
108 ])
109 |> json.to_string
110
111 let req =
112 simulate.request(http.Post, "/oauth/register")
113 |> simulate.string_body(body)
114 |> simulate.header("content-type", "application/json")
115
116 let response = register.handle(req, exec)
117
118 // Should return 201 Created - localhost http is allowed
119 response.status |> should.equal(201)
120}
121
122pub fn register_valid_scope_test() {
123 let assert Ok(exec) = test_helpers.create_test_db()
124 let assert Ok(_) = test_helpers.create_all_tables(exec)
125
126 let body =
127 json.object([
128 #("client_name", json.string("Test Client")),
129 #(
130 "redirect_uris",
131 json.array([json.string("https://example.com/callback")], fn(x) { x }),
132 ),
133 #("scope", json.string("atproto repo:* account:email")),
134 ])
135 |> json.to_string
136
137 let req =
138 simulate.request(http.Post, "/oauth/register")
139 |> simulate.string_body(body)
140 |> simulate.header("content-type", "application/json")
141
142 let response = register.handle(req, exec)
143
144 response.status |> should.equal(201)
145
146 case response.body {
147 wisp.Text(response_body) -> {
148 response_body |> string.contains("client_id") |> should.be_true
149 response_body
150 |> string.contains("atproto repo:* account:email")
151 |> should.be_true
152 }
153 _ -> should.fail()
154 }
155}
156
157pub fn register_invalid_scope_test() {
158 let assert Ok(exec) = test_helpers.create_test_db()
159 let assert Ok(_) = test_helpers.create_all_tables(exec)
160
161 let body =
162 json.object([
163 #("client_name", json.string("Test Client")),
164 #(
165 "redirect_uris",
166 json.array([json.string("https://example.com/callback")], fn(x) { x }),
167 ),
168 #("scope", json.string("atproto invalid:::")),
169 ])
170 |> json.to_string
171
172 let req =
173 simulate.request(http.Post, "/oauth/register")
174 |> simulate.string_body(body)
175 |> simulate.header("content-type", "application/json")
176
177 let response = register.handle(req, exec)
178
179 // Should return 400 with invalid_scope error
180 response.status |> should.equal(400)
181
182 case response.body {
183 wisp.Text(response_body) -> {
184 response_body |> string.contains("invalid_scope") |> should.be_true
185 }
186 _ -> should.fail()
187 }
188}