Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion project.clj
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@
:milia-http-default-per-route "10"
:milia-http-threads "20"})

(defproject onaio/milia "0.9.3-rc2"
(defproject onaio/milia "0.9.4-rc2"
:description "The ona.io Clojure Web API Client."
:dependencies [;; CORE MILIA REQUIREMENTS
[cheshire "6.2.0"]
Expand Down
117 changes: 117 additions & 0 deletions src/milia/api/v2/organization.cljc
Original file line number Diff line number Diff line change
@@ -0,0 +1,117 @@
(ns milia.api.v2.organization
"Organizations through the v2 API.

Unlike v1, an organization does not carry its `users`: its members, with
their roles, come from `members`, and the role of the user making the
request is the organization's `current_user_role`. The list only carries
what identifies each organization."
(:refer-clojure :exclude [update])
(:require [milia.api.http :refer [parse-http]]
[milia.utils.remote :refer [make-v2-url]]))

(def editor-role "editor")

(defn all
"List the organizations the account making the request belongs to.
`shared-with` keeps only those the user with that username also belongs
to, and `role` only those where the account making the request holds that
role or a higher one."
[& {:keys [shared-with role]}]
(let [params (cond-> {}
shared-with (assoc :shared_with shared-with)
role (assoc :role role))]
(parse-http :get
(make-v2-url "orgs.json")
:http-options {:query-params params})))

(defn create [data]
(let [url (make-v2-url "orgs.json")]
(parse-http :post url :http-options {:form-params data}
:suppress-4xx-exceptions? true
:as-map? true)))

(defn profile
[org-name & {:keys [no-cache?]}]
(when (seq org-name)
(let [url (make-v2-url "orgs" (str org-name ".json"))]
(parse-http :get url :no-cache? no-cache?))))

(defn retrieve-org-metadata
[username]
(:metadata (profile username)))

(defn update
"update organization profile"
[params]
(let [org-name (:org params)
url (make-v2-url "orgs" (str org-name ".json"))
params (dissoc params :org)]
(when (seq org-name)
(parse-http
:patch
url
:http-options
#?(:clj {:form-params params
:content-type :json})
#?(:cljs {:json-params params})
:as-map? true))))

(defn members
"Every member of an organization with their role, as v1 returned them in
the organization's `users`."
[org-name]
(parse-http :get (make-v2-url "orgs" org-name "members.json")))

(defn add-member
"Add a user to an organization"
([org-name member]
(add-member org-name member nil))
([org-name member role]
(let [url (make-v2-url "orgs" org-name "members.json")
data {:username member
:role (or role editor-role)}]
(parse-http :post
url
:http-options
#?(:clj {:form-params data
:content-type :json})
#?(:cljs {:json-params data})
:suppress-4xx-exceptions? true
:as-map? true))))

(defn change-member-role
"Change the role of an organization member"
[org-name member role]
(let [data {:username member
:role role}]
(parse-http :put
(make-v2-url "orgs" org-name "members.json")
:http-options
#?(:clj {:form-params data
:content-type :json})
#?(:cljs {:json-params data})
:as-map? true)))

(defn remove-member
"Remove a user from an organization. v2 has no DELETE on the members: a
member is removed by updating them with `remove`."
[org-name member]
(let [data {:username member
:remove true}]
(parse-http :patch
(make-v2-url "orgs" org-name "members.json")
:http-options
#?(:clj {:form-params data
:content-type :json})
#?(:cljs {:json-params data})
:as-map? true)))

;; CLJ only: in CLJS `members` returns a channel, not the members
#?(:clj
(defn single-owner-member?
"Is user only members in org with owner role?"
[org-name]
(->> (members org-name)
(filter #(= "owner" (:role %)))
count
(= 1))))
5 changes: 5 additions & 0 deletions src/milia/utils/remote.cljc
Original file line number Diff line number Diff line change
Expand Up @@ -95,6 +95,11 @@
[& postfix]
(url-join (str (protocol-prefixed (:data @hosts)) "/api/v1") postfix))

(defn make-v2-url
"Build a v2 API url."
[& postfix]
(url-join (str (protocol-prefixed (:data @hosts)) "/api/v2") postfix))

(defn make-client-url
"Build a URL pointing to the client."
[& postfix]
Expand Down
128 changes: 128 additions & 0 deletions test/clj/milia/api/v2/organization_test.clj
Original file line number Diff line number Diff line change
@@ -0,0 +1,128 @@
(ns milia.api.v2.organization-test
(:refer-clojure :exclude [update])
(:require [midje.sweet :refer :all]
[milia.api.v2.organization :refer :all]
[milia.api.http :refer [parse-http]]
[milia.utils.remote :refer [make-v2-url]]))

(def url "fake-url")
(def org-name "fake-org-name")

(facts "about all"
(fact "should list without filters"
(all) => :something
(provided
(make-v2-url "orgs.json") => url
(parse-http :get url :http-options {:query-params {}})
=> :something))

(fact "should pass the shared-with and role filters"
(all :shared-with "bob" :role "manager") => :something
(provided
(make-v2-url "orgs.json") => url
(parse-http :get
url
:http-options {:query-params {:shared_with "bob"
:role "manager"}})
=> :something)))

(fact "about create"
(create :data) => :something
(provided
(make-v2-url "orgs.json") => url
(parse-http :post
url
:http-options {:form-params :data}
:suppress-4xx-exceptions? true
:as-map? true) => :something))

(facts "about profile"
(fact "should get the organization"
(profile org-name) => :something
(provided
(make-v2-url "orgs" (str org-name ".json")) => url
(parse-http :get url :no-cache? nil) => :something))

(fact "should not request without an organization"
(profile "") => nil))

(fact "should retrieve org metadata"
(retrieve-org-metadata org-name) => :metadata
(provided
(profile org-name) => {:metadata :metadata}))

(fact "should update the organization"
(update {:org org-name :description "test"}) => :something
(provided
(make-v2-url "orgs" (str org-name ".json")) => url
(parse-http :patch
url
:http-options {:form-params {:description "test"}
:content-type :json}
:as-map? true) => :something))

(fact "about members"
(members org-name) => :something
(provided
(make-v2-url "orgs" org-name "members.json") => url
(parse-http :get url) => :something))

(facts "about add-member"
(fact "should add a member with the default role"
(add-member org-name "bob") => :something
(provided
(make-v2-url "orgs" org-name "members.json") => url
(parse-http :post
url
:http-options {:form-params {:username "bob"
:role editor-role}
:content-type :json}
:suppress-4xx-exceptions? true
:as-map? true) => :something))

(fact "should add a member with the given role"
(add-member org-name "bob" "owner") => :something
(provided
(make-v2-url "orgs" org-name "members.json") => url
(parse-http :post
url
:http-options {:form-params {:username "bob"
:role "owner"}
:content-type :json}
:suppress-4xx-exceptions? true
:as-map? true) => :something)))

(fact "about change-member-role"
(change-member-role org-name "bob" "manager") => :something
(provided
(make-v2-url "orgs" org-name "members.json") => url
(parse-http :put
url
:http-options {:form-params {:username "bob"
:role "manager"}
:content-type :json}
:as-map? true) => :something))

(fact "should remove a member by updating them with remove"
(remove-member org-name "bob") => :something
(provided
(make-v2-url "orgs" org-name "members.json") => url
(parse-http :patch
url
:http-options {:form-params {:username "bob"
:remove true}
:content-type :json}
:as-map? true) => :something))

(facts "about single-owner-member?"
(fact "should be true with one owner"
(single-owner-member? org-name) => true
(provided
(members org-name) => [{:user "a" :role "owner"}
{:user "b" :role "manager"}]))

(fact "should be false with several owners"
(single-owner-member? org-name) => false
(provided
(members org-name) => [{:user "a" :role "owner"}
{:user "b" :role "owner"}])))
6 changes: 6 additions & 0 deletions test/clj/milia/utils/remote_test.clj
Original file line number Diff line number Diff line change
Expand Up @@ -44,3 +44,9 @@
:password :password
:temp-token :temp-token
:token :token})))

(facts "about make-v2-url"
(fact "should build a url on the v2 API"
(make-v2-url "orgs" "bob.json")
=> (str (protocol-prefixed (:data @hosts))
"/api/v2/orgs/bob.json")))
Loading