Skip to content

Commit 720cbc6

Browse files
Merge pull request #37 from clj-codes/feat/adds-social-info-on-author-api
Adds Social Info on Authors API
2 parents 25a6688 + c009a89 commit 720cbc6

File tree

12 files changed

+238
-51
lines changed

12 files changed

+238
-51
lines changed

src/codes/clj/docs/backend/adapters/db/postgres.clj

Lines changed: 9 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -77,9 +77,9 @@
7777
(filter #(= (:type %) "see-also"))
7878
(map db->see-also)))
7979

80-
(defn db->social
80+
(defn db->socials
8181
{:malli/schema [:=> [:cat [:sequential schemas.db/Row]]
82-
[:maybe schemas.model.social/Social]]}
82+
[:maybe [:sequential schemas.model.social/Social]]]}
8383
[db-rows]
8484
(->> db-rows
8585
(group-by :definition-id)
@@ -90,5 +90,10 @@
9090
{:social/definition-id definition-id
9191
:social/notes notes
9292
:social/examples examples
93-
:social/see-alsos see-alsos})))
94-
first))
93+
:social/see-alsos see-alsos})))))
94+
95+
(defn db->social-definition
96+
{:malli/schema [:=> [:cat [:sequential schemas.db/Row]]
97+
[:maybe schemas.model.social/Social]]}
98+
[db-rows]
99+
(first (db->socials db-rows)))

src/codes/clj/docs/backend/adapters/social.clj

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -121,3 +121,11 @@
121121
:notes (map note->model->wire notes)
122122
:examples (map example->model->wire examples)
123123
:see-alsos (map see-also->model->wire see-alsos)})
124+
125+
(defn author+socials->model->wire
126+
{:malli/schema [:=> [:cat schemas.model.social/Author+Socials]
127+
schemas.wire.out.social/Author+Socials]}
128+
[{:author/keys [socials] :as author}]
129+
(enc/assoc-some
130+
(author->model->wire author)
131+
:socials (map social->model->wire socials)))

src/codes/clj/docs/backend/controllers/social.clj

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -9,11 +9,11 @@
99
[new-author {:keys [database]}]
1010
(db.postgres/upsert-author new-author database))
1111

12-
(defn get-author
12+
(defn get-author+socials
1313
{:malli/schema [:=> [:cat :string schemas.model.social/account-source schemas.types/Components]
14-
[:maybe schemas.model.social/Author]]}
14+
[:maybe schemas.model.social/Author+Socials]]}
1515
[login source {:keys [database]}]
16-
(db.postgres/get-author login source database))
16+
(db.postgres/get-author+socials login source database))
1717

1818
(defn insert-see-also
1919
{:malli/schema [:=> [:cat schemas.model.social/NewSeeAlso schemas.types/Components]

src/codes/clj/docs/backend/db/postgres.clj

Lines changed: 48 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -5,41 +5,14 @@
55
[honey.sql :as sql]
66
[honey.sql.helpers :as sql.helpers]
77
[next.jdbc :as jdbc]
8-
[parenthesin.components.db.jdbc-hikari :as components.database]))
8+
[parenthesin.components.db.jdbc-hikari :as components.database]
9+
[taoensso.encore :as enc]))
910

1011
(defn ^:private execute!
1112
{:malli/schema [:=> [:cat schemas.types/DatabaseComponent :any] :any]}
1213
[db sql-params]
1314
(components.database/execute db sql-params jdbc/unqualified-snake-kebab-opts))
1415

15-
(defn upsert-author
16-
{:malli/schema [:=> [:cat schemas.model.social/NewAuthor schemas.types/DatabaseComponent]
17-
schemas.model.social/Author]}
18-
[transaction db]
19-
(->> (-> (sql.helpers/insert-into :author)
20-
(sql.helpers/values [transaction])
21-
(sql.helpers/upsert (-> (sql.helpers/on-conflict :login :account_source)
22-
(sql.helpers/do-update-set :avatar_url)))
23-
(sql.helpers/returning :*)
24-
sql/format)
25-
(execute! db)
26-
first
27-
adapters/db->author))
28-
29-
(defn get-author
30-
{:malli/schema [:=> [:cat :string schemas.model.social/account-source schemas.types/DatabaseComponent]
31-
[:maybe schemas.model.social/Author]]}
32-
[login source db]
33-
(when-let [author (->> (-> (sql.helpers/select :*)
34-
(sql.helpers/from :author)
35-
(sql.helpers/where :and
36-
[:= :login login]
37-
[:= :account_source source])
38-
sql/format)
39-
(execute! db)
40-
first)]
41-
(adapters/db->author author)))
42-
4316
(defn insert-see-also
4417
{:malli/schema [:=> [:cat schemas.model.social/NewSeeAlso schemas.types/DatabaseComponent]
4518
schemas.model.social/SeeAlso]}
@@ -259,6 +232,51 @@
259232
first
260233
adapters/db->note))
261234

235+
(defn upsert-author
236+
{:malli/schema [:=> [:cat schemas.model.social/NewAuthor schemas.types/DatabaseComponent]
237+
schemas.model.social/Author]}
238+
[transaction db]
239+
(->> (-> (sql.helpers/insert-into :author)
240+
(sql.helpers/values [transaction])
241+
(sql.helpers/upsert (-> (sql.helpers/on-conflict :login :account_source)
242+
(sql.helpers/do-update-set :avatar_url)))
243+
(sql.helpers/returning :*)
244+
sql/format)
245+
(execute! db)
246+
first
247+
adapters/db->author))
248+
249+
(defn get-author+socials
250+
{:malli/schema [:=> [:cat :string schemas.model.social/account-source schemas.types/DatabaseComponent]
251+
[:maybe schemas.model.social/Author+Socials]]}
252+
[login source db]
253+
(when-let [author (->> (-> (sql.helpers/select :*)
254+
(sql.helpers/from :author)
255+
(sql.helpers/where :and
256+
[:= :login login]
257+
[:= :account_source source])
258+
sql/format)
259+
(execute! db)
260+
first)]
261+
(let [author-id (:author-id author)
262+
socials (->> (-> (sql.helpers/union-all
263+
(-> get-note-query
264+
(sql.helpers/where [:= :note/author-id author-id]))
265+
266+
(-> get-example-query
267+
(sql.helpers/where [:= :example-edit/author-id author-id]))
268+
269+
(-> get-see-also-query
270+
(sql.helpers/where [:= :see-also/author-id author-id])))
271+
sql/format)
272+
(execute! db)
273+
adapters/db->socials
274+
seq)]
275+
276+
(enc/assoc-some
277+
(adapters/db->author author)
278+
:author/socials socials))))
279+
262280
(defn get-by-definition
263281
{:malli/schema [:=> [:cat :string schemas.types/DatabaseComponent]
264282
[:maybe schemas.model.social/Social]]}
@@ -274,4 +292,4 @@
274292
(sql.helpers/where [:= :see-also/definition-id definition-id])))
275293
sql/format)
276294
(execute! db)
277-
adapters/db->social))
295+
adapters/db->social-definition))

src/codes/clj/docs/backend/ports/http_in/social.clj

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -16,12 +16,12 @@
1616
:body {:author author
1717
:access-token access-token}}))
1818

19-
(defn get-author
19+
(defn get-author+socials
2020
[{{{:keys [login source]} :path} :parameters
2121
components :components}]
22-
(if-let [author (controllers.social/get-author login source components)]
22+
(if-let [author (controllers.social/get-author+socials login source components)]
2323
{:status 200
24-
:body (adapters.social/author->model->wire author)}
24+
:body (adapters.social/author+socials->model->wire author)}
2525
{:status 404
2626
:body "not found"}))
2727

src/codes/clj/docs/backend/routes.clj

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -45,14 +45,14 @@
4545

4646
["/author"
4747
["/:login/:source"
48-
{:get {:summary "get author by login and source"
48+
{:get {:summary "get author and social interactions (if any) by login and source"
4949
:parameters {:path {:login :string
5050
:source :string}}
51-
:responses {200 {:body schemas.wire.social/Author}
51+
:responses {200 {:body schemas.wire.out.social/Author+Socials}
5252
400 {:body :string}
5353
404 {:body :string}
5454
500 {:body :string}}
55-
:handler ports.http-in.social/get-author}}]]
55+
:handler ports.http-in.social/get-author+socials}}]]
5656

5757
["/example"
5858
["/:example-id"

src/codes/clj/docs/backend/schemas/model/social.clj

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -110,3 +110,6 @@
110110
[:social/notes [:sequential Note]]
111111
[:social/examples [:sequential Example]]
112112
[:social/see-alsos [:sequential SeeAlso]]])
113+
114+
(def Author+Socials
115+
(mu/assoc Author [:author/socials {:optional true}] [:sequential Social]))

src/codes/clj/docs/backend/schemas/wire/out/social.clj

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
(ns codes.clj.docs.backend.schemas.wire.out.social
2-
(:require [codes.clj.docs.backend.schemas.wire.social :refer [example note
3-
see-also]]
2+
(:require [codes.clj.docs.backend.schemas.wire.social :refer [Author example
3+
note see-also]]
44
[malli.util :as mu]))
55

66
(def SeeAlso
@@ -32,3 +32,6 @@
3232
[:notes [:sequential Note]]
3333
[:examples [:sequential Example]]
3434
[:see-alsos [:sequential SeeAlso]]])
35+
36+
(def Author+Socials
37+
(mu/assoc Author [:socials {:optional true}] [:sequential Social]))

test/integration/codes/clj/docs/backend/db/postgres_test.clj

Lines changed: 33 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -26,9 +26,31 @@
2626
:cleanup util/stop-system!
2727
:fail-fast? true}
2828

29-
[database (state-flow.api/get-state :database)]
30-
31-
(util.db.postgres/upsert-author "delboni" "github")
29+
[database (state-flow.api/get-state :database)
30+
31+
; prepare db authors
32+
author-1 (util.db.postgres/upsert-author "delboni" "github")
33+
author-2 (util.db.postgres/upsert-author "not-delboni" "github")
34+
35+
; prepare socials
36+
see-also-1 (util.db.postgres/create-see-also {:see-also/author-id (:author/author-id author-1)
37+
:see-also/definition-id "clojure.core/disj"
38+
:see-also/definition-id-to "clojure.core/dissoc"})
39+
_see-also-2 (util.db.postgres/create-see-also {:see-also/author-id (:author/author-id author-2)
40+
:see-also/definition-id "clojure.core/disj"
41+
:see-also/definition-id-to "clojure.core/dissoc2"})
42+
note-1 (util.db.postgres/create-note {:note/author-id (:author/author-id author-1)
43+
:note/definition-id "clojure.core/disj"
44+
:note/body "author 1 note about this function."})
45+
_note-2 (util.db.postgres/create-note {:note/author-id (:author/author-id author-2)
46+
:note/definition-id "clojure.core/disj"
47+
:note/body "author 2 note about this function."})
48+
example-1 (util.db.postgres/create-example {:example/author-id (:author/author-id author-1)
49+
:example/definition-id "clojure.core/disj"
50+
:example/body "author 1 example about this function."})
51+
_example-2 (util.db.postgres/create-example {:example/author-id (:author/author-id author-2)
52+
:example/definition-id "clojure.core/disj"
53+
:example/body "author 2 example about this function."})]
3254

3355
(flow "upsert author with new url"
3456
(state/invoke
@@ -42,8 +64,14 @@
4264
:author/login "delboni"
4365
:author/account-source "github"
4466
:author/avatar-url "https://my.pic.com/me2.jpg"
45-
:author/created-at inst?}
46-
(db/get-author "delboni" "github" database))))
67+
:author/created-at inst?
68+
:author/socials [{:social/definition-id "clojure.core/disj"
69+
:social/notes [note-1]
70+
:social/examples [(dissoc example-1
71+
:example/author-id)]
72+
:social/see-alsos [see-also-1]}]}
73+
74+
(db/get-author+socials "delboni" "github" database))))
4775

4876
(defflow see-also-db-test
4977
{:init (util/start-system! create-and-start-components!)

test/integration/codes/clj/docs/backend/social_test.clj

Lines changed: 62 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -141,6 +141,23 @@
141141
(state-flow.server/request! {:method :get
142142
:uri (str "/api/social/note/" note-id)})))
143143

144+
(flow "should return author + socials"
145+
(match? {:status 200
146+
:body {:author-id string?
147+
:login "delboni",
148+
:account-source "github",
149+
:avatar-url "https://my.pic/me.jpg",
150+
:created-at string?
151+
:socials [{:definition-id "clojure.core/disj"
152+
:notes [{:note-id note-id
153+
:definition-id "clojure.core/disj"
154+
:body "my edited note about this function."
155+
:created-at string?}]
156+
:examples []
157+
:see-alsos []}]}}
158+
(state-flow.server/request! {:method :get
159+
:uri "/api/social/author/delboni/github"})))
160+
144161
(flow "should not be able to delete if not allowed"
145162
(match? {:status 403
146163
:body "You not allowed to delete this note."}
@@ -212,6 +229,22 @@
212229
:created-at string?}}
213230
(state-flow.server/request! {:method :get
214231
:uri (str "/api/social/see-also/" see-also-id)})))
232+
(flow "should return author + socials"
233+
(match? {:status 200
234+
:body {:author-id string?
235+
:login "delboni",
236+
:account-source "github",
237+
:avatar-url "https://my.pic/me.jpg",
238+
:created-at string?
239+
:socials [{:definition-id "clojure.core/disj"
240+
:notes []
241+
:examples []
242+
:see-alsos [{:see-also-id see-also-id
243+
:definition-id "clojure.core/disj"
244+
:definition-id-to "clojure.core/dissoc"
245+
:created-at string?}]}]}}
246+
(state-flow.server/request! {:method :get
247+
:uri "/api/social/author/delboni/github"})))
215248

216249
(flow "should not be able to delete if not allowed"
217250
(match? {:status 403
@@ -324,6 +357,35 @@
324357
(state-flow.server/request! {:method :get
325358
:uri (str "/api/social/example/" example-id)})))
326359

360+
(flow "should return author"
361+
(match? {:status 200
362+
:body {:author-id string?
363+
:login "delboni",
364+
:account-source "github",
365+
:avatar-url "https://my.pic/me.jpg",
366+
:created-at string?
367+
:socials [{:definition-id "clojure.core/disj"
368+
:notes []
369+
:see-alsos []
370+
:examples [{:example-id example-id
371+
:definition-id "clojure.core/disj"
372+
:body "my edited example about this function."
373+
:created-at string?
374+
:editors [{:author-id string?
375+
:login "delboni"
376+
:account-source "github"
377+
:avatar-url "https://my.pic/me.jpg"
378+
:created-at string?
379+
:edited-at string?}
380+
{:author-id string?
381+
:login "delboni"
382+
:account-source "github"
383+
:avatar-url "https://my.pic/me.jpg"
384+
:created-at string?
385+
:edited-at string?}]}]}]}}
386+
(state-flow.server/request! {:method :get
387+
:uri "/api/social/author/delboni/github"})))
388+
327389
(flow "delete example revision part 1"
328390
(state-flow.server/request! {:method :delete
329391
:headers {"authorization" (str "Bearer " token)}

0 commit comments

Comments
 (0)