Skip to content
Snippets Groups Projects
Commit 621f2516 authored by Allen Gilliland's avatar Allen Gilliland
Browse files

tidying up dashboard api unit tests a bit before we start. also added a unit...

tidying up dashboard api unit tests a bit before we start.  also added a unit test for the reposition endpoint, which was missing.
parent f5e70aad
No related branches found
No related tags found
No related merge requests found
......@@ -54,9 +54,8 @@
(write-check Dashboard id)
(check-500 (upd-non-nil-keys Dashboard id
:description description
:name name
:public_perms public_perms))
(events/publish-event :dashboard-update {:id id :actor_id *current-user-id*}))
:name name))
(events/publish-event :dashboard-update (assoc (sel :one Dashboard :id id) :actor_id *current-user-id*)))
(defendpoint DELETE "/:id"
"Delete a `Dashboard`."
......
......@@ -2,161 +2,263 @@
"Tests for /api/dashboard endpoints."
(:require [expectations :refer :all]
[metabase.api.card-test :refer [post-card]]
[metabase.db :refer :all]
[metabase.db :as db]
[metabase.driver.query-processor.expand :as ql]
[metabase.http-client :as http]
[metabase.middleware :as middleware]
(metabase.models [hydrate :refer [hydrate]]
[card :refer [Card]]
[common :as common]
[dashboard :refer [Dashboard]]
[dashboard-card :refer [DashboardCard]]
[user :refer [User]])
[metabase.test.data :refer :all]
[metabase.test.data.users :refer :all]
[metabase.test.util :refer [match-$ expect-eval-actual-first random-name with-temp obj->json->obj]]))
[metabase.test.util :as tu]
[korma.core :as k]))
;; # DASHBOARD LIFECYCLE
;; ## Helper Fns
(defn create-dash [dash-name]
((user->client :rasta) :post 200 "dashboard" {:name dash-name
:public_perms 0}))
(defn user-details [user]
(tu/match-$ user
{:id $
:email $
:date_joined $
:first_name $
:last_name $
:last_login $
:is_superuser $
:common_name $}))
(defn dashcard-response [{:keys [card created_at updated_at] :as dashcard}]
(-> (into {} dashcard)
(dissoc :id :dashboard_id :card_id)
(assoc :created_at (not (nil? created_at)))
(assoc :updated_at (not (nil? updated_at)))
(assoc :card (-> (into {} card)
(dissoc :id :database_id :table_id :created_at :updated_at)))))
(defn dashboard-response [{:keys [creator ordered_cards created_at updated_at] :as dashboard}]
(let [dash (-> (into {} dashboard)
(dissoc :id)
(assoc :created_at (not (nil? created_at)))
(assoc :updated_at (not (nil? updated_at))))]
(cond-> dash
creator (update :creator #(into {} %))
ordered_cards (update :ordered_cards #(mapv dashcard-response %)))))
;; ## /api/dashboard/* AUTHENTICATION Tests
;; We assume that all endpoints for a given context are enforced by the same middleware, so we don't run the same
;; authentication test on every single individual endpoint
(expect (get middleware/response-unauthentic :body) (http/client :get 401 "dashboard"))
(expect (get middleware/response-unauthentic :body) (http/client :put 401 "dashboard/13"))
;; ## POST /api/dash
;; Test that we can create a new Dashboard
(let [dash-name (random-name)]
(expect-eval-actual-first
(match-$ (sel :one Dashboard :name dash-name)
{:description nil
:organization_id nil
:name dash-name
:creator_id (user->id :rasta)
:updated_at $
:id $
:public_perms 0
:created_at $})
(create-dash dash-name)))
;; test validations
(expect {:errors {:name "field is a required param."}}
((user->client :rasta) :post 400 "dashboard" {}))
(expect
{:name "Test Create Dashboard"
:description nil
:creator_id (user->id :rasta)
:public_perms 0
:updated_at true
:created_at true
:organization_id nil}
(-> ((user->client :rasta) :post 200 "dashboard" {:name "Test Create Dashboard"
:public_perms 0})
dashboard-response))
;; ## GET /api/dashboard/:id
;; Test that we can fetch a Dashboard, and that it comes back wrapped in a "dashboard" dictionary (WHY?!)
(expect-let [dash (create-dash (random-name))]
{:dashboard
(match-$ dash
{:description nil
:can_read true
:ordered_cards []
:creator (-> (User (user->id :rasta))
(select-keys [:email :first_name :last_login :is_superuser :id :last_name :date_joined :common_name]))
:can_write true
:organization_id nil
:name $
:creator_id (user->id :rasta)
:updated_at $
:id $
:public_perms 0
:created_at $})}
((user->client :rasta) :get 200 (format "dashboard/%d" (:id dash))))
;; Check that only the creator of a Dashboard sees it when it isn't public
(expect [true
false]
(with-temp Dashboard [{:keys [id]} {:name (random-name)
:public_perms common/perms-none
:creator_id (user->id :crowberto)}]
(let [can-see-dash? (fn [user]
(contains? (->> ((user->client user) :get 200 "dashboard" :f :all)
(map :id)
set)
id))]
[(can-see-dash? :crowberto)
(can-see-dash? :rasta)])))
(expect
{:dashboard {:name "Test Dashboard"
:description nil
:creator_id (user->id :rasta)
:creator (user-details (fetch-user :rasta))
:public_perms 0
:can_read true
:can_write true
:updated_at true
:created_at true
:ordered_cards [{:sizeX 2
:sizeY 2
:col nil
:row nil
:updated_at true
:created_at true
:card {:name "Dashboard Test Card"
:description nil
:public_perms 0
:creator_id (user->id :rasta)
:creator (user-details (fetch-user :rasta))
:organization_id nil
:display "scalar"
:query_type nil
:dataset_query {:something "simple"}
:visualization_settings {:global {:title nil}}}}]
:organization_id nil}}
;; fetch a dashboard WITH a dashboard card on it
(tu/with-temp Dashboard [{dashboard-id :id} {:name "Test Dashboard"
:public_perms 0
:creator_id (user->id :rasta)}]
(tu/with-temp Card [{card-id :id} {:name "Dashboard Test Card"
:creator_id (user->id :rasta)
:public_perms 0
:display "scalar"
:dataset_query {:something "simple"}
:visualization_settings {:global {:title nil}}}]
(tu/with-temp DashboardCard [_ {:dashboard_id dashboard-id
:card_id card-id}]
(-> ((user->client :rasta) :get 200 (format "dashboard/%d" dashboard-id))
(update :dashboard dashboard-response))))))
;; ## PUT /api/dashboard/:id
;; Test that we can change a Dashboard
(expect-let [[old-name new-name] (repeatedly 2 random-name)
{:keys [id]} (create-dash old-name)
get-dash (fn []
(sel :one :fields [Dashboard :name :description :public_perms] :id id))]
[{:name old-name
:description nil
:public_perms 0}
{:name new-name
:description "My Cool Dashboard"
:public_perms 2}
{:name old-name
:description "My Cool Dashboard"
:public_perms 2}]
[(get-dash)
(do ((user->client :rasta) :put 200 (format "dashboard/%d" id) {:description "My Cool Dashboard"
:public_perms 2
:name new-name})
(get-dash))
;; See if we can change just the name without affecting other fields
(do ((user->client :rasta) :put 200 (format "dashboard/%d" id) {:name old-name})
(get-dash))])
(expect
[{:name "Test Dashboard"
:description nil
:creator_id (user->id :rasta)
:public_perms 0
:updated_at true
:created_at true
:organization_id nil}
{:name "My Cool Dashboard"
:description "Some awesome description"
:actor_id (user->id :rasta)
:creator_id (user->id :rasta)
:public_perms 0
:updated_at true
:created_at true
:organization_id nil}
{:name "My Cool Dashboard"
:description "Some awesome description"
:creator_id (user->id :rasta)
:public_perms 0
:updated_at true
:created_at true
:organization_id nil}]
(tu/with-temp Dashboard [{dashboard-id :id} {:name "Test Dashboard"
:public_perms 0
:creator_id (user->id :rasta)}]
(->> [(Dashboard dashboard-id)
((user->client :rasta) :put 200 (format "dashboard/%d" dashboard-id) {:name "My Cool Dashboard"
:description "Some awesome description"
;; these things should fail to update
:public_perms 2
:creator_id (user->id :trashbird)})
(Dashboard dashboard-id)]
(mapv dashboard-response))))
;; ## DELETE /api/dashboard/:id
(expect-let [{:keys [id]} (create-dash (random-name))]
nil
(do ((user->client :rasta) :delete 204 (format "dashboard/%d" id))
(Dashboard id)))
(expect
[nil nil]
(tu/with-temp Dashboard [{dashboard-id :id} {:name "Test Dashboard"
:public_perms 0
:creator_id (user->id :rasta)}]
[((user->client :rasta) :delete 204 (format "dashboard/%d" dashboard-id))
(Dashboard dashboard-id)]))
;; # DASHBOARD CARD ENDPOINTS
;; ## POST /api/dashboard/:id/cards
;; Can we add a Card to a Dashboard?
(let [card-name (random-name)
dash-name (random-name)]
(expect-eval-actual-first
(let [{card-id :id :as card} (sel :one Card :name card-name)
dash-id (sel :one :id Dashboard :name dash-name)]
[(match-$ (sel :one DashboardCard :dashboard_id dash-id :card_id card-id)
{:sizeX 2
:card (match-$ card
{:description nil
:creator (-> (User (user->id :rasta))
(select-keys [:date_joined :last_name :id :is_superuser :last_login :first_name :email :common_name]))
:organization_id nil
:name $
:creator_id (user->id :rasta)
:updated_at $
:dataset_query (obj->json->obj (ql/wrap-inner-query
(query categories
(ql/aggregation (ql/count)))))
:id card-id
:display "scalar"
:visualization_settings {:global {:title nil}}
:public_perms 0
:created_at $
:database_id (id)
:table_id (id :categories)
:query_type "query"})
:updated_at $
:col nil
:id $
:card_id card-id
:dashboard_id dash-id
:created_at $
:sizeY 2
:row nil})])
(let [{card-id :id} (post-card card-name)
{dash-id :id} (create-dash dash-name)]
((user->client :rasta) :post 200 (format "dashboard/%d/cards" dash-id) {:cardId card-id})
(->> ((user->client :rasta) :get 200 (format "dashboard/%d" dash-id))
:dashboard
:ordered_cards))))
(expect
[{:sizeX 2
:sizeY 2
:col nil
:row nil
:created_at true
:updated_at true}
[{:sizeX 2
:sizeY 2
:col nil
:row nil}]]
(tu/with-temp Dashboard [{dashboard-id :id} {:name "Test Dashboard"
:public_perms 0
:creator_id (user->id :rasta)}]
(tu/with-temp Card [{card-id :id} {:name "Dashboard Test Card"
:creator_id (user->id :rasta)
:public_perms 0
:display "scalar"
:dataset_query {:something "simple"}
:visualization_settings {:global {:title nil}}}]
[(-> ((user->client :rasta) :post 200 (format "dashboard/%d/cards" dashboard-id) {:cardId card-id})
(dissoc :id :dashboard_id :card_id)
(update :created_at #(not (nil? %)))
(update :updated_at #(not (nil? %))))
(db/sel :many :fields [DashboardCard :sizeX :sizeY :col :row] :dashboard_id dashboard-id)])))
;; ## DELETE /api/dashboard/:id/cards
(let [card-name (random-name)
dash-name (random-name)]
(expect-eval-actual-first
[]
(let [{card-id :id} (post-card card-name)
{dash-id :id} (create-dash dash-name)
{dashcard-id :id} ((user->client :rasta) :post 200 (format "dashboard/%d/cards" dash-id) {:cardId card-id})]
((user->client :rasta) :delete 204 (format "dashboard/%d/cards" dash-id) :dashcardId dashcard-id)
(->> ((user->client :rasta) :get 200 (format "dashboard/%d" dash-id))
:dashboard
:ordered_cards))))
(expect
[1
nil
0]
;; fetch a dashboard WITH a dashboard card on it
(tu/with-temp Dashboard [{dashboard-id :id} {:name "Test Dashboard"
:public_perms 0
:creator_id (user->id :rasta)}]
(tu/with-temp Card [{card-id :id} {:name "Dashboard Test Card"
:creator_id (user->id :rasta)
:public_perms 0
:display "scalar"
:dataset_query {:something "simple"}
:visualization_settings {:global {:title nil}}}]
(tu/with-temp DashboardCard [{dashcard-id :id} {:dashboard_id dashboard-id
:card_id card-id}]
[(count (db/sel :many :field [DashboardCard :id] :dashboard_id dashboard-id))
((user->client :rasta) :delete 204 (format "dashboard/%d/cards" dashboard-id) :dashcardId dashcard-id)
(count (db/sel :many :field [DashboardCard :id] :dashboard_id dashboard-id))]))))
;; ## POST /api/dashboard/:id/reposition
(expect
[[{:sizeX 2
:sizeY 2
:col nil
:row nil}
{:sizeX 2
:sizeY 2
:col nil
:row nil}]
{:status "ok"}
[{:sizeX 4
:sizeY 2
:col 0
:row 0}
{:sizeX 1
:sizeY 1
:col 1
:row 3}]]
;; fetch a dashboard WITH a dashboard card on it
(tu/with-temp Dashboard [{dashboard-id :id} {:name "Test Dashboard"
:public_perms 0
:creator_id (user->id :rasta)}]
(tu/with-temp Card [{card-id :id} {:name "Dashboard Test Card"
:creator_id (user->id :rasta)
:public_perms 0
:display "scalar"
:dataset_query {:something "simple"}
:visualization_settings {:global {:title nil}}}]
(tu/with-temp DashboardCard [{dashcard-id1 :id} {:dashboard_id dashboard-id
:card_id card-id}]
(tu/with-temp DashboardCard [{dashcard-id2 :id} {:dashboard_id dashboard-id
:card_id card-id}]
[(db/sel :many :fields [DashboardCard :sizeX :sizeY :row :col] :dashboard_id dashboard-id (k/order :id :asc))
((user->client :rasta) :post 200 (format "dashboard/%d/reposition" dashboard-id) {:cards [{:id dashcard-id1
:sizeX 4
:sizeY 2
:col 0
:row 0}
{:id dashcard-id2
:sizeX 1
:sizeY 1
:col 1
:row 3}]})
(db/sel :many :fields [DashboardCard :sizeX :sizeY :row :col] :dashboard_id dashboard-id (k/order :id :asc))])))))
(ns metabase.models.card-test
(:require [expectations :refer :all]
(metabase.api [card-test :refer [post-card]]
[dashboard-test :refer [create-dash]])
(metabase.api [card-test :refer [post-card]])
[metabase.db :refer [ins]]
(metabase.models [card :refer :all]
[dashboard-card :refer [DashboardCard]])
[metabase.test.data.users :refer :all]
[metabase.test.util :refer [random-name]]))
(defn create-dash [dash-name]
((user->client :rasta) :post 200 "dashboard" {:name dash-name
:public_perms 0}))
;; Check that the :dashboard_count delay returns the correct count of Dashboards a Card is in
(expect [0 1 2]
(let [{card-id :id} (post-card (random-name))
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment