Commit 80fa522
authored
Expand Profile API client (#379)
This PR makes some general improvements to the `ProfileApiClient` before
expanding it to implement the following additional functionality in
Profile API:
- Listing students
- Getting a student
- Updating a student
- Deleting a student
Overview of other changes in this PR:
- Use Ruby's `Data` class to return value objects from some of our
`ProfileApiClient` methods. I prefer this to passing hashes around as I
think it makes the code easier to reason about and because it means we
fail fast if the response we receive from the Profile API is different
to what we're expecting.
- Configure Faraday to raise exceptions for 4xx and 5xx responses from
Profile API. The only one of these responses we can currently handle is
the 422 Unprocessable Entity response that can be returned when creating
or updating a student.
- Raise a ProfileApiClient::UnexpectedResponse exception if we receive
any other notionally successful response (i.e. not 4xx or 5xx) than the
response we're expecting.
- Remove boiler plate code and unnecessary comments
## Examples of using this client to interact with Profile API
```ruby
> token = '<your-token>'
# Create a school
> school = ProfileApiClient.create_school(token:, id: SecureRandom.uuid, code: SchoolCodeGenerator.generate)
=> #<data ProfileApiClient::School id="bd1ef16c-7f80-4c04-9d2f-8689a7bd4511", schoolCode="06-27-42", updatedAt="2024-07-10T14:24:15.130Z", createdAt="2024-07-10T14:24:15.130Z", discardedAt=nil>
# List safeguarding flags - user only has teacher flag
> ProfileApiClient.safeguarding_flags(token:)
=>
[#<data ProfileApiClient::SafeguardingFlag
id="5f741142-ad7b-41bb-9722-f6ea4b37b2ee",
userId="583ba872-b16e-46e1-9f7d-df89d267550d",
flag="school:teacher",
email="[email protected]",
createdAt="2024-07-10T14:22:20.392Z",
updatedAt="2024-07-10T14:22:20.392Z",
discardedAt=nil>]
# Create owner safeguarding flag
> ProfileApiClient.create_safeguarding_flag(token:, flag: ProfileApiClient::SAFEGUARDING_FLAGS[:owner])
=> nil
# Delete teacher safeguarding flag
> ProfileApiClient.delete_safeguarding_flag(token:, flag: ProfileApiClient::SAFEGUARDING_FLAGS[:teacher])
=> nil
# List safeguarding flags - user only has owner flag
> ProfileApiClient.safeguarding_flags(token:)
=>
[#<data ProfileApiClient::SafeguardingFlag
id="6137f101-ac60-4365-8ec9-91d5ffbd198b",
userId="583ba872-b16e-46e1-9f7d-df89d267550d",
flag="school:owner",
email="[email protected]",
createdAt="2024-07-10T14:25:49.912Z",
updatedAt="2024-07-10T14:25:49.912Z",
discardedAt=nil>]
# Create a student
> response = ProfileApiClient.create_school_student(token:, school_id: school.id, username: 'username', password: 'password$123', name: 'name')
=> {:created=>["62045970-5957-4ac0-b8a1-96ae59dac58d"]}
> student_id = response[:created].first
=> "62045970-5957-4ac0-b8a1-96ae59dac58d"
# Create a student for non-existent school
> ProfileApiClient.create_school_student(token:, school_id: SecureRandom.uuid, username: 'username', password: 'password$123', name: 'name')
lib/profile_api_client.rb:105:in 'create_school_student': the server responded with status 404 (Faraday::ResourceNotFound)
# Create a student with invalid password
> ProfileApiClient.create_school_student(token:, school_id: school.id, username: 'username', password: 'password', name: 'name')
lib/profile_api_client.rb:117:in 'rescue in create_school_student': Student not saved in Profile API (status code 422, username 'username', error 'password is invalid') (ProfileApiClient::Student422Error)
# Create a student with duplicate username
> ProfileApiClient.create_school_student(token:, school_id: school.id, username: 'username', password: 'password$123', name: 'name')
lib/profile_api_client.rb:117:in 'rescue in create_school_student': Student not saved in Profile API (status code 422, username 'username', error 'username has already been taken') (ProfileApiClient::Student422Error)
# Get student
> ProfileApiClient.school_student(token:, school_id: school.id, student_id:)
=>
#<data ProfileApiClient::Student
id="62045970-5957-4ac0-b8a1-96ae59dac58d",
schoolId="bd1ef16c-7f80-4c04-9d2f-8689a7bd4511",
name="name",
username="username",
createdAt="2024-07-10T14:27:50.147Z",
updatedAt="2024-07-10T14:27:50.147Z",
discardedAt=nil>
# Update student
> ProfileApiClient.update_school_student(token:, school_id: school.id, student_id:, username: 'new-username', password: 'new-password', name: 'new-name')
=>
#<data ProfileApiClient::Student
id="62045970-5957-4ac0-b8a1-96ae59dac58d",
schoolId="bd1ef16c-7f80-4c04-9d2f-8689a7bd4511",
name="new-name",
username="new-username",
createdAt="2024-07-10T14:27:50.147Z",
updatedAt="2024-07-10T14:33:19.707Z",
discardedAt=nil>
# List students
> ProfileApiClient.list_school_students(token:, school_id: school.id, student_ids: [student_id])
=>
[#<data ProfileApiClient::Student
id="62045970-5957-4ac0-b8a1-96ae59dac58d",
schoolId="bd1ef16c-7f80-4c04-9d2f-8689a7bd4511",
name="new-name",
username="new-username",
createdAt="2024-07-10T14:27:50.147Z",
updatedAt="2024-07-10T14:33:19.707Z",
discardedAt=nil>]
# List students - error unless all student ids belong to school in Profile API
> ProfileApiClient.list_school_students(token:, school_id: school.id, student_ids: [student_id, SecureRandom.uuid])
lib/profile_api_client.rb:93:in 'list_school_students': the server responded with status 404 (Faraday::ResourceNotFound)
# Delete student
> ProfileApiClient.delete_school_student(token:, school_id: school.id, student_id:)
=> nil
```File tree
13 files changed
+488
-219
lines changed- app/controllers/api
- lib
- concepts/school_student
- spec
- concepts/school_student
- features/school_student
- lib
- support
13 files changed
+488
-219
lines changed| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
39 | 39 | | |
40 | 40 | | |
41 | 41 | | |
42 | | - | |
| 42 | + | |
| 43 | + | |
| 44 | + | |
43 | 45 | | |
44 | 46 | | |
45 | 47 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
7 | 7 | | |
8 | 8 | | |
9 | 9 | | |
10 | | - | |
| 10 | + | |
11 | 11 | | |
12 | 12 | | |
13 | 13 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
16 | 16 | | |
17 | 17 | | |
18 | 18 | | |
19 | | - | |
| 19 | + | |
20 | 20 | | |
21 | 21 | | |
22 | 22 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
16 | 16 | | |
17 | 17 | | |
18 | 18 | | |
19 | | - | |
20 | | - | |
21 | | - | |
22 | | - | |
| 19 | + | |
| 20 | + | |
| 21 | + | |
| 22 | + | |
23 | 23 | | |
24 | 24 | | |
25 | 25 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
3 | 3 | | |
4 | 4 | | |
5 | 5 | | |
6 | | - | |
| 6 | + | |
7 | 7 | | |
8 | | - | |
| 8 | + | |
9 | 9 | | |
10 | 10 | | |
11 | 11 | | |
| |||
15 | 15 | | |
16 | 16 | | |
17 | 17 | | |
18 | | - | |
| 18 | + | |
19 | 19 | | |
20 | 20 | | |
21 | 21 | | |
22 | 22 | | |
23 | 23 | | |
24 | 24 | | |
25 | | - | |
26 | | - | |
27 | | - | |
28 | | - | |
| 25 | + | |
| 26 | + | |
| 27 | + | |
29 | 28 | | |
30 | 29 | | |
31 | 30 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
6 | 6 | | |
7 | 7 | | |
8 | 8 | | |
| 9 | + | |
| 10 | + | |
| 11 | + | |
| 12 | + | |
9 | 13 | | |
10 | 14 | | |
11 | | - | |
| 15 | + | |
12 | 16 | | |
13 | 17 | | |
14 | 18 | | |
| |||
23 | 27 | | |
24 | 28 | | |
25 | 29 | | |
26 | | - | |
| 30 | + | |
27 | 31 | | |
28 | 32 | | |
29 | 33 | | |
30 | | - | |
31 | | - | |
| 34 | + | |
| 35 | + | |
| 36 | + | |
| 37 | + | |
| 38 | + | |
| 39 | + | |
| 40 | + | |
| 41 | + | |
| 42 | + | |
| 43 | + | |
| 44 | + | |
32 | 45 | | |
| 46 | + | |
33 | 47 | | |
34 | 48 | | |
35 | 49 | | |
| |||
40 | 54 | | |
41 | 55 | | |
42 | 56 | | |
43 | | - | |
| 57 | + | |
44 | 58 | | |
45 | | - | |
| 59 | + | |
46 | 60 | | |
47 | 61 | | |
48 | | - | |
49 | | - | |
50 | | - | |
51 | | - | |
52 | | - | |
53 | | - | |
54 | | - | |
55 | | - | |
56 | | - | |
57 | | - | |
58 | | - | |
59 | | - | |
60 | | - | |
61 | | - | |
62 | | - | |
63 | | - | |
| 62 | + | |
| 63 | + | |
64 | 64 | | |
65 | 65 | | |
66 | | - | |
67 | | - | |
68 | | - | |
69 | | - | |
70 | | - | |
71 | | - | |
72 | | - | |
73 | | - | |
74 | | - | |
75 | | - | |
76 | | - | |
77 | | - | |
78 | | - | |
79 | | - | |
80 | | - | |
81 | | - | |
82 | | - | |
83 | | - | |
| 66 | + | |
| 67 | + | |
84 | 68 | | |
85 | 69 | | |
86 | | - | |
87 | | - | |
88 | | - | |
89 | | - | |
90 | | - | |
91 | | - | |
92 | | - | |
93 | | - | |
94 | | - | |
95 | | - | |
96 | | - | |
97 | | - | |
98 | | - | |
99 | | - | |
100 | | - | |
101 | | - | |
102 | | - | |
103 | | - | |
| 70 | + | |
| 71 | + | |
104 | 72 | | |
105 | 73 | | |
106 | | - | |
107 | | - | |
108 | | - | |
109 | | - | |
110 | | - | |
111 | | - | |
112 | | - | |
113 | | - | |
114 | | - | |
115 | | - | |
116 | | - | |
| 74 | + | |
| 75 | + | |
| 76 | + | |
117 | 77 | | |
118 | | - | |
119 | | - | |
120 | | - | |
121 | | - | |
| 78 | + | |
| 79 | + | |
122 | 80 | | |
123 | 81 | | |
124 | | - | |
125 | | - | |
126 | | - | |
127 | | - | |
128 | | - | |
129 | | - | |
130 | | - | |
131 | | - | |
132 | | - | |
133 | | - | |
| 82 | + | |
| 83 | + | |
134 | 84 | | |
135 | | - | |
136 | | - | |
| 85 | + | |
137 | 86 | | |
138 | | - | |
139 | | - | |
140 | | - | |
141 | | - | |
| 87 | + | |
142 | 88 | | |
143 | 89 | | |
144 | | - | |
145 | | - | |
146 | | - | |
147 | | - | |
148 | | - | |
149 | | - | |
150 | | - | |
151 | | - | |
| 90 | + | |
152 | 91 | | |
153 | 92 | | |
154 | | - | |
| 93 | + | |
| 94 | + | |
| 95 | + | |
| 96 | + | |
| 97 | + | |
155 | 98 | | |
156 | | - | |
157 | | - | |
158 | | - | |
159 | | - | |
| 99 | + | |
160 | 100 | | |
161 | 101 | | |
162 | | - | |
163 | | - | |
164 | | - | |
165 | | - | |
166 | | - | |
167 | | - | |
168 | | - | |
169 | | - | |
170 | | - | |
171 | 102 | | |
172 | 103 | | |
173 | 104 | | |
| |||
179 | 110 | | |
180 | 111 | | |
181 | 112 | | |
182 | | - | |
183 | | - | |
| 113 | + | |
184 | 114 | | |
185 | 115 | | |
| 116 | + | |
| 117 | + | |
186 | 118 | | |
187 | | - | |
188 | 119 | | |
189 | | - | |
190 | | - | |
191 | | - | |
192 | | - | |
193 | | - | |
194 | | - | |
195 | | - | |
196 | | - | |
197 | | - | |
198 | | - | |
| 120 | + | |
| 121 | + | |
199 | 122 | | |
200 | 123 | | |
201 | | - | |
202 | | - | |
| 124 | + | |
| 125 | + | |
| 126 | + | |
| 127 | + | |
| 128 | + | |
| 129 | + | |
| 130 | + | |
| 131 | + | |
| 132 | + | |
203 | 133 | | |
204 | | - | |
205 | | - | |
206 | | - | |
207 | | - | |
| 134 | + | |
| 135 | + | |
| 136 | + | |
208 | 137 | | |
| 138 | + | |
209 | 139 | | |
210 | | - | |
211 | | - | |
212 | | - | |
213 | | - | |
214 | | - | |
215 | | - | |
216 | | - | |
217 | | - | |
218 | | - | |
219 | | - | |
| 140 | + | |
220 | 141 | | |
221 | 142 | | |
222 | | - | |
223 | | - | |
| 143 | + | |
224 | 144 | | |
225 | | - | |
226 | | - | |
227 | | - | |
228 | | - | |
| 145 | + | |
229 | 146 | | |
230 | 147 | | |
231 | 148 | | |
232 | 149 | | |
233 | 150 | | |
234 | | - | |
235 | | - | |
236 | | - | |
| 151 | + | |
237 | 152 | | |
238 | | - | |
| 153 | + | |
239 | 154 | | |
240 | 155 | | |
241 | 156 | | |
242 | 157 | | |
243 | 158 | | |
244 | 159 | | |
245 | 160 | | |
246 | | - | |
247 | | - | |
248 | | - | |
| 161 | + | |
249 | 162 | | |
250 | 163 | | |
251 | 164 | | |
252 | 165 | | |
253 | 166 | | |
254 | | - | |
255 | | - | |
256 | | - | |
| 167 | + | |
257 | 168 | | |
258 | 169 | | |
259 | 170 | | |
| |||
262 | 173 | | |
263 | 174 | | |
264 | 175 | | |
| 176 | + | |
265 | 177 | | |
266 | 178 | | |
267 | 179 | | |
| |||
0 commit comments