diff --git a/src/metabase/api/collection.clj b/src/metabase/api/collection.clj
index c1261ec76c4978ae1558493db0081b7d3810704f..1140b01094b1b447e3e1c57bee69c462bfc305c9 100644
--- a/src/metabase/api/collection.clj
+++ b/src/metabase/api/collection.clj
@@ -4,10 +4,14 @@
   `:snippet` namespace, (called 'Snippet folders' in the UI). These namespaces are completely independent hierarchies.
   To use these endpoints for other Collections namespaces, you can pass the `?namespace=` parameter (e.g.
   `?namespace=snippet`)."
-  (:require [compojure.core :refer [GET POST PUT]]
+  (:require [clojure.string :as str]
+            [compojure.core :refer [GET POST PUT]]
+            [honeysql.core :as hsql]
             [honeysql.helpers :as h]
+            [medley.core :as m]
             [metabase.api.card :as card-api]
             [metabase.api.common :as api]
+            [metabase.db.env :as mdb.env]
             [metabase.models.card :refer [Card]]
             [metabase.models.collection :as collection :refer [Collection]]
             [metabase.models.collection.graph :as collection.graph]
@@ -91,12 +95,18 @@
   "Valid values for the `?pinned_state` param accepted by endpoints in this namespace."
   #{"all" "is_pinned" "is_not_pinned"})
 
+(def ^:private valid-sort-columns #{"name" "last_edited" "model"})
+(def ^:private valid-sort-directions #{"asc" "desc"})
+(defn- normalize-sort-choice [w] (when w (keyword (str/replace w #"_" "-"))))
+
 
 (def ^:private CollectionChildrenOptions
-  {:archived?      s/Bool
-   :pinned-state   (s/maybe (apply s/enum (map keyword valid-pinned-state-values)))
+  {:archived?    s/Bool
+   :pinned-state (s/maybe (apply s/enum (map keyword valid-pinned-state-values)))
    ;; when specified, only return results of this type.
-   :models         (s/maybe #{(apply s/enum (map keyword valid-model-param-values))})})
+   :models       (s/maybe #{(apply s/enum (map keyword valid-model-param-values))})
+   :sort-info    (s/maybe [(s/one (apply s/enum (map normalize-sort-choice valid-sort-columns)) "sort-columns")
+                           (s/one (apply s/enum (map normalize-sort-choice valid-sort-directions)) "sort-direction")])})
 
 (defmulti ^:private collection-children-query
   "Query that will fetch the 'children' of a `collection`, for different types of objects. Possible options are listed
@@ -105,7 +115,11 @@
   NOTES:
 
   *  `collection` will be either a CollectionInstance, or the Root Collection special placeholder object, so do not use
-     `u/the-id` on it! Use `:id`, which will return `nil` for the Root Collection, which is exactly what we want."
+     `u/the-id` on it! Use `:id`, which will return `nil` for the Root Collection, which is exactly what we want.
+
+  * These queries will be combined into a union-all query. You do not need to put all of the columns into the query,
+  any you don't select will be added in the correct position so the union will work (see `all-select-columns` for more
+  details)."
   {:arglists '([model collection options])}
   (fn [model _ _] (keyword model)))
 
@@ -132,9 +146,7 @@
   [_ collection {:keys [archived? pinned-state]}]
   (-> {:select    [:p.id
                    :p.name
-                   [nil :p.description]
                    :p.collection_position
-                   [nil :p.display]
                    [(hx/literal "pulse") :model]]
        :modifiers [:distinct]
        :from      [[Pulse :p]]
@@ -155,7 +167,7 @@
 
 (defmethod collection-children-query :snippet
   [_ collection {:keys [archived? pinned-state]}]
-  {:select [:id :name [nil :description] [nil :collection_position] [nil :display] [(hx/literal "snippet") :model]]
+  {:select [:id :name [(hx/literal "snippet") :model]]
        :from   [[NativeQuerySnippet :nqs]]
        :where  [:and
                 [:= :collection_id (:id collection)]
@@ -168,38 +180,58 @@
 
 (defmethod collection-children-query :card
   [_ collection {:keys [archived? pinned-state]}]
-  (-> {:select [:id :name :description :collection_position :display [(hx/literal "card") :model]]
-       :from   [[Card :c]]
-       :where  [:and
-                [:= :collection_id (:id collection)]
-                [:= :archived (boolean archived?)]]}
+  (-> {:select    [:c.id :c.name :c.description :c.collection_position :c.display [(hx/literal "card") :model]
+                   [:u.id :last_edit_user] [:u.email :last_edit_email]
+                   [:u.first_name :last_edit_first_name] [:u.last_name :last_edit_last_name]
+                   [:r.timestamp :last_edit_timestamp]]
+       :from      [[Card :c]]
+       ;; todo: should there be a flag, or a realized view?
+       :left-join [[{:select [:r1.*]
+                     :from [[:revision :r1]]
+                     :left-join [[:revision :r2] [:and
+                                                  [:= :r1.model_id :r2.model_id]
+                                                  [:= :r1.model :r2.model]
+                                                  [:> :r1.id :r2.id]]]
+                     :where [:and
+                             [:= :r2.id nil]
+                             [:= :r1.model (hx/literal "Card")]]} :r]
+                   [:= :r.model_id :c.id]
+                   [:core_user :u] [:= :u.id :r.user_id]]
+       :where     [:and
+                   [:= :collection_id (:id collection)]
+                   [:= :archived (boolean archived?)]]}
       (h/merge-where (pinned-state->clause pinned-state))))
 
 (defmethod post-process-collection-children :card
   [_ rows]
-  (let [last-edits (last-edit/fetch-last-edited-info {:card-ids (->> rows (map :id))})]
-    (for [row (hydrate rows :favorite)]
-        (if-let [edit-info (get-in last-edits [:card (:id row)])]
-          (assoc row :last-edit-info edit-info)
-          row))))
+  (hydrate rows :favorite))
 
 (defmethod collection-children-query :dashboard
   [_ collection {:keys [archived? pinned-state]}]
-  (-> {:select [:id :name :description :collection_position [nil :display] [(hx/literal "dashboard") :model]]
-       :from   [[Dashboard :d]]
-       :where  [:and
-                [:= :collection_id (:id collection)]
-                [:= :archived (boolean archived?)]]}
+  (-> {:select    [:d.id :d.name :d.description :d.collection_position [(hx/literal "dashboard") :model]
+                   [:u.id :last_edit_user] [:u.email :last_edit_email]
+                   [:u.first_name :last_edit_first_name] [:u.last_name :last_edit_last_name]
+                   [:r.timestamp :last_edit_timestamp]]
+       :from      [[Dashboard :d]]
+       :left-join [[{:select [:r1.*]
+                     :from [[:revision :r1]]
+                     :left-join [[:revision :r2] [:and
+                                                  [:= :r1.model_id :r2.model_id]
+                                                  [:= :r1.model :r2.model]
+                                                  [:> :r1.id :r2.id]]]
+                     :where [:and
+                             [:= :r2.id nil]
+                             [:= :r1.model (hx/literal "Dashboard")]]} :r]
+                   [:= :r.model_id :d.id]
+                   [:core_user :u] [:= :u.id :r.user_id]]
+       :where     [:and
+                   [:= :collection_id (:id collection)]
+                   [:= :archived (boolean archived?)]]}
       (h/merge-where (pinned-state->clause pinned-state))))
 
 (defmethod post-process-collection-children :dashboard
   [_ rows]
-  (let [last-edits (last-edit/fetch-last-edited-info {:dashboard-ids (->> rows (map :id))})]
-    (for [row (hydrate rows :favorite)]
-      (let [res (dissoc row :display)]
-        (if-let [edit-info (get-in last-edits [:dashboard (:id res)])]
-          (assoc res :last-edit-info edit-info)
-          res)))))
+  (hydrate (map #(dissoc % :display) rows) :favorite))
 
 (defmethod collection-children-query :collection
   [_ collection {:keys [archived? collection-namespace pinned-state]}]
@@ -212,8 +244,6 @@
              :select [:id
                       :name
                       :description
-                      [nil :collection_position]
-                      [nil :display]
                       [(hx/literal "collection") :model]])
       ;; the nil indicates that collections are never pinned.
       (h/merge-where (pinned-state->clause pinned-state nil))))
@@ -229,11 +259,35 @@
            :can_write
            (mi/can-write? Collection (:id row)))))
 
-(defn- post-process-rows [rows]
-  (mapcat
-    (fn [[model rows]]
-      (post-process-collection-children (keyword model) rows))
-    (group-by :model rows)))
+(s/defn ^:private coalesce-edit-info :- last-edit/MaybeAnnotated
+  "Hoist all of the last edit information into a map under the key :last-edit-info. Considers this information present
+  if `:last_edit_user` is not nil."
+  [row]
+  (letfn [(select-as [original k->k']
+            (reduce (fn [m [k k']] (assoc m k' (get original k)))
+                    {}
+                    k->k'))]
+    (let [mapping {:last_edit_user       :id
+                   :last_edit_last_name  :last_name
+                   :last_edit_first_name :first_name
+                   :last_edit_email      :email
+                   :last_edit_timestamp  :timestamp}]
+      (cond-> (apply dissoc row :model_ranking (keys mapping))
+        ;; don't use contains as they all have the key, we care about a value present
+        (:last_edit_user row) (assoc :last-edit-info (select-as row mapping))))))
+
+(defn- post-process-rows
+  "Post process any data. Have a chance to process all of the same type at once using
+  `post-process-collection-children`. Must respect the order passed in."
+  [rows]
+  (->> (map-indexed (fn [i row] (vary-meta row assoc ::index i)) rows) ;; keep db sort order
+       (group-by :model)
+       (into []
+             (comp (map (fn [[model rows]]
+                          (post-process-collection-children (keyword model) rows)))
+                   cat
+                   (map coalesce-edit-info)))
+       (sort-by (comp ::index meta))))
 
 (defn- model-name->toucan-model [model-name]
   (case (keyword model-name)
@@ -243,20 +297,92 @@
     :pulse      Pulse
     :snippet    NativeQuerySnippet))
 
+(defn- select-name
+  "Takes a honeysql select column and returns a keyword of which column it is.
+
+  eg:
+  (select-name :id) -> :id
+  (select-name [(literal \"card\") :model]) -> :model
+  (select-name :p.id) -> :id"
+  [x]
+  (if (vector? x)
+    (recur (second x))
+    (-> x name (str/split #"\.") peek keyword)))
+
+(def ^:private all-select-columns
+  "All columns that need to be present for the union-all. Generated with the comment form below. Non-text columns that
+  are optional (not id, but last_edit_user for example) must have a type so that the union-all can unify the nil with
+  the correct column type."
+  [:id :name :description :display :model :collection_position
+   :last_edit_email :last_edit_first_name :last_edit_last_name
+   [:last_edit_user :integer] [:last_edit_timestamp :timestamp]])
+
+(defn- add-missing-columns
+  "Ensures that all necessary columns are in the select-columns collection, adding `[nil :column]` as necessary."
+  [select-columns necessary-columns]
+  (let [columns (m/index-by select-name select-columns)]
+    (map (fn [col]
+           (let [[col-name typpe] (u/one-or-many col)]
+             (get columns col-name (if (and typpe (= @mdb.env/db-type :postgres))
+                                     [(hx/cast typpe nil) col-name]
+                                     [nil col-name]))))
+         necessary-columns)))
+
+(defn- add-model-ranking
+  [select-clause model]
+  (let [rankings {:dashboard  1
+                  :pulse      2
+                  :card       3
+                  :snippet    4
+                  :collection 5}]
+    (conj select-clause [(get rankings model 100)
+                         :model_ranking])))
+
+(comment
+  ;; generate the set of columns across all child queries. Remember to add type info if not a text column
+  (into []
+        (comp cat (map select-name) (distinct))
+        (for [model [:card :dashboard :snippet :pulse :collection]]
+          (:select (collection-children-query model {:id 1 :location "/"} nil))))
+  )
+
 (defn- collection-children*
-  [collection models options]
-  (let [models            (sort (map keyword models))
-        queries           (for [model models]
-                            (collection-children-query model collection options))
-        total-query       {:select [[:%count.* :count]]
-                           :from   [[{:union-all queries} :dummy_alias]]}
-        rows-query        {:select   [:*]
-                           :from     [[{:union-all queries} :dummy_alias]]
-                           :order-by [[:%lower.name :asc]]
-                           :limit    offset-paging/*limit*
-                           :offset   offset-paging/*offset*}]
-    {:total  (-> (db/query total-query) first :count)
-     :data   (-> (db/query rows-query) post-process-rows)
+  [collection models {:keys [sort-info] :as options}]
+  (let [sql-order   (case sort-info
+                      nil                  [[:%lower.name :asc]]
+                      [:name :asc]         [[:%lower.name :asc]]
+                      [:name :desc]        [[:%lower.name :desc]]
+                      [:last-edited :asc]  [(if (= @mdb.env/db-type :mysql)
+                                              [(hsql/call :ISNULL :last_edit_timestamp)]
+                                              [:last_edit_timestamp :nulls-last])
+                                            [:last_edit_timestamp :asc]
+                                            [:%lower.name :asc]]
+                      [:last-edited :desc] (into
+                                            (case @mdb.env/db-type
+                                              :mysql
+                                              [[(hsql/call :ISNULL :last_edit_timestamp)]]
+                                              :postgres
+                                              [[(hsql/raw "last_edit_timestamp DESC NULLS LAST")]]
+                                              :h2
+                                              [])
+                                            [[:last_edit_timestamp :desc]
+                                             [:%lower.name :asc]])
+                      [:model :asc]        [[:model_ranking :asc]  [:%lower.name :asc]]
+                      [:model :desc]       [[:model_ranking :desc] [:%lower.name :asc]])
+        models      (sort (map keyword models))
+        queries     (for [model models]
+                      (-> (collection-children-query model collection options)
+                          (update :select add-missing-columns all-select-columns)
+                          (update :select add-model-ranking model)))
+        total-query {:select [[:%count.* :count]]
+                     :from   [[{:union-all queries} :dummy_alias]]}
+        rows-query  {:select   [:*]
+                     :from     [[{:union-all queries} :dummy_alias]]
+                     :order-by sql-order
+                     :limit    offset-paging/*limit*
+                     :offset   offset-paging/*offset*}]
+    {:total  (->> (db/query total-query) first :count)
+     :data   (->> (db/query rows-query) post-process-rows)
      :limit  offset-paging/*limit*
      :offset offset-paging/*offset*
      :models models}))
@@ -295,15 +421,19 @@
   *  `pinned_state` - when `is_pinned`, return pinned objects only.
                    when `is_not_pinned`, return non pinned objects only.
                    when `all`, return everything. By default returns everything"
-  [id models archived pinned_state]
-  {models       (s/maybe models-schema)
-   archived     (s/maybe su/BooleanString)
-   pinned_state (s/maybe (apply s/enum valid-pinned-state-values))}
-  (let [model-kwds    (set (map keyword (u/one-or-many models)))]
+  [id models archived pinned_state sort_column sort_direction]
+  {models         (s/maybe models-schema)
+   archived       (s/maybe su/BooleanString)
+   pinned_state   (s/maybe (apply s/enum valid-pinned-state-values))
+   sort_column    (s/maybe (apply s/enum valid-sort-columns))
+   sort_direction (s/maybe (apply s/enum valid-sort-directions))}
+  (let [model-kwds (set (map keyword (u/one-or-many models)))]
     (collection-children (api/read-check Collection id)
                          {:models       model-kwds
                           :archived?    (Boolean/parseBoolean archived)
-                          :pinned-state (keyword pinned_state)})))
+                          :pinned-state (keyword pinned_state)
+                          :sort-info    [(or (some-> sort_column normalize-sort-choice) :name)
+                                         (or (some-> sort_direction normalize-sort-choice) :asc)]})))
 
 
 ;;; -------------------------------------------- GET /api/collection/root --------------------------------------------
@@ -331,11 +461,13 @@
 
   By default, this will show the 'normal' Collections namespace; to view a different Collections namespace, such as
   `snippets`, you can pass the `?namespace=` parameter."
-  [models archived namespace pinned_state]
-  {models       (s/maybe models-schema)
-   archived     (s/maybe su/BooleanString)
-   namespace    (s/maybe su/NonBlankString)
-   pinned_state (s/maybe (apply s/enum valid-pinned-state-values))}
+  [models archived namespace pinned_state sort_column sort_direction]
+  {models         (s/maybe models-schema)
+   archived       (s/maybe su/BooleanString)
+   namespace      (s/maybe su/NonBlankString)
+   pinned_state   (s/maybe (apply s/enum valid-pinned-state-values))
+   sort_column    (s/maybe (apply s/enum valid-sort-columns))
+   sort_direction (s/maybe (apply s/enum valid-sort-directions))}
   ;; Return collection contents, including Collections that have an effective location of being in the Root
   ;; Collection for the Current User.
   (let [root-collection (assoc collection/root-collection :namespace namespace)
@@ -344,9 +476,11 @@
                           #{:collection})]
     (collection-children
       root-collection
-      {:models         model-kwds
-       :archived?      (Boolean/parseBoolean archived)
-       :pinned-state   (keyword pinned_state)})))
+      {:models       model-kwds
+       :archived?    (Boolean/parseBoolean archived)
+       :pinned-state (keyword pinned_state)
+       :sort-info    [(or (some-> sort_column normalize-sort-choice) :name)
+                      (or (some-> sort_direction normalize-sort-choice) :asc)]})))
 
 
 ;;; ----------------------------------------- Creating/Editing a Collection ------------------------------------------
diff --git a/test/metabase/api/collection_test.clj b/test/metabase/api/collection_test.clj
index 23a2b1cff1390dede8b5663f528dbfecd8e50c62..47bd6ddde70f855f5beebec9af9af17ce2b08a0e 100644
--- a/test/metabase/api/collection_test.clj
+++ b/test/metabase/api/collection_test.clj
@@ -16,7 +16,8 @@
             [metabase.test.fixtures :as fixtures]
             [metabase.util :as u]
             [schema.core :as s]
-            [toucan.db :as db]))
+            [toucan.db :as db])
+  (:import [java.time ZonedDateTime ZoneId]))
 
 (use-fixtures :once (fixtures/initialize :test-users-personal-collections))
 
@@ -301,15 +302,15 @@
       (mt/with-temp* [Collection [collection]
                       Card       [card        {:collection_id (u/the-id collection)}]]
         (is (= (mt/obj->json->obj
-                 [{:id                  (u/the-id card)
-                   :name                (:name card)
-                   :collection_position nil
-                   :display             "table"
-                   :description         nil
-                   :favorite            false
-                   :model               "card"}])
+                [{:id                  (u/the-id card)
+                  :name                (:name card)
+                  :collection_position nil
+                  :display             "table"
+                  :description         nil
+                  :favorite            false
+                  :model               "card"}])
                (mt/obj->json->obj
-                 (:data (mt/user-http-request :crowberto :get 200 (str "collection/" (u/the-id collection) "/items"))))))))
+                (:data (mt/user-http-request :crowberto :get 200 (str "collection/" (u/the-id collection) "/items"))))))))
     (testing "check that limit and offset work and total comes back"
       (mt/with-temp* [Collection [collection]
                       Card       [card3        {:collection_id (u/the-id collection)}]
@@ -332,9 +333,9 @@
         (perms/grant-collection-read-permissions! (group/all-users) collection)
         (with-some-children-of-collection collection
           (is (= (map default-item [{:name "Acme Products", :model "pulse"}
-                                    {:name "Electro-Magnetic Pulse", :model "pulse"}
                                     {:name "Birthday Card", :description nil, :favorite false, :model "card", :display "table"}
-                                    {:name "Dine & Dashboard", :description nil, :favorite false, :model "dashboard"}])
+                                    {:name "Dine & Dashboard", :description nil, :favorite false, :model "dashboard"}
+                                    {:name "Electro-Magnetic Pulse", :model "pulse"}])
                  (mt/boolean-ids-and-timestamps
                   (:data (mt/user-http-request :rasta :get 200 (str "collection/" (u/the-id collection) "/items"))))))))
 
@@ -359,26 +360,77 @@
           (is (= [(default-item {:name "Dine & Dashboard", :description nil, :favorite false, :model "dashboard"})]
                  (mt/boolean-ids-and-timestamps
                   (:data (mt/user-http-request :rasta :get 200 (str "collection/" (u/the-id collection) "/items?archived=true")))))))))
-    (testing "Results include last edited information from the `Revision` table"
-      (mt/with-temp* [Collection [{collection-id :id} {:name "Collection with Items"}]
-                      User       [{user-id :id} {:first_name "Test" :last_name "User" :email "testuser@example.com"}]
-                      Card       [{card-id :id :as card}
-                                  {:name          "Card with history" :collection_id collection-id}]
-                      Revision   [_revision {:model    "Card"
-                                             :model_id card-id
-                                             :user_id  user-id
-                                             :object   (revision/serialize-instance card card-id card)}]]
-        (is (= [{:name "Card with history",
+    (mt/with-temp* [Collection [{collection-id :id} {:name "Collection with Items"}]
+                    User       [{user-id :id} {:first_name "Test" :last_name "User" :email "testuser@example.com"}]
+                    Card       [{card1-id :id :as card1}
+                                {:name "Card with history 1" :collection_id collection-id}]
+                    Card       [{card2-id :id :as card2}
+                                {:name "Card with history 2" :collection_id collection-id}]
+                    Card       [_ {:name "ZZ" :collection_id collection-id}]
+                    Card       [_ {:name "AA" :collection_id collection-id}]
+                    Revision   [_revision1 {:model    "Card"
+                                            :model_id card1-id
+                                            :user_id  user-id
+                                            :object   (revision/serialize-instance card1 card1-id card1)}]
+                    Revision   [_revision2 {:model    "Card"
+                                            :model_id card2-id
+                                            :user_id  user-id
+                                            :object   (revision/serialize-instance card2 card2-id card2)}]]
+      ;; need different timestamps and Revision has a pre-update to throw as they aren't editable
+      (db/execute! {:update :revision
+                    ;; in the past
+                    :set {:timestamp (.minusHours (ZonedDateTime/now (ZoneId/of "UTC")) 2)}
+                    :where [:= :id (:id _revision1)]})
+      (testing "Results include last edited information from the `Revision` table"
+        (is (= [{:name "AA"}
+                {:name "Card with history 1",
                  :last-edit-info
                  {:id         true,
                   :email      "testuser@example.com",
                   :first_name "Test",
                   :last_name  "User",
                   ;; timestamp collapsed to true, ordinarily a OffsetDateTime
-                  :timestamp  true}}]
+                  :timestamp  true}}
+                {:name "Card with history 2",
+                 :last-edit-info
+                 {:id         true,
+                  :email      "testuser@example.com",
+                  :first_name "Test",
+                  :last_name  "User",
+                  :timestamp  true}}
+                {:name "ZZ"}]
                (->> (:data (mt/user-http-request :rasta :get 200 (str "collection/" collection-id "/items")))
                     mt/boolean-ids-and-timestamps
-                    (map #(select-keys % [:name :last-edit-info])))))))))
+                    (map #(select-keys % [:name :last-edit-info]))))))
+      (testing "Results can be ordered by last-edited"
+        (testing "ascending"
+          (is (= ["Card with history 1" "Card with history 2" "AA" "ZZ"]
+                 (->> (mt/user-http-request :rasta :get 200 (str "collection/" collection-id "/items?sort_column=last_edited&sort_direction=asc"))
+                      :data
+                      (map :name)))))
+        (testing "descending"
+          (is (= ["Card with history 2" "Card with history 1" "AA" "ZZ"]
+                 (->> (mt/user-http-request :rasta :get 200 (str "collection/" collection-id "/items?sort_column=last_edited&sort_direction=desc"))
+                      :data
+                      (map :name))))))
+      (testing "Results can be ordered by model"
+        (mt/with-temp* [Collection [{collection-id :id} {:name "Collection with Items"}]
+                        Card       [_ {:name "ZZ" :collection_id collection-id}]
+                        Card       [_ {:name "AA" :collection_id collection-id}]
+                        Dashboard  [_ {:name "ZZ" :collection_id collection-id}]
+                        Dashboard  [_ {:name "AA" :collection_id collection-id}]
+                        Pulse      [_ {:name "ZZ" :collection_id collection-id}]
+                        Pulse      [_ {:name "AA" :collection_id collection-id}]]
+          (testing "sort direction asc"
+            (is (= [["dashboard" "AA"] ["dashboard" "ZZ"] ["pulse" "AA"] ["pulse" "ZZ"] ["card" "AA"] ["card" "ZZ"]]
+                   (->> (mt/user-http-request :rasta :get 200 (str "collection/" collection-id "/items?sort_column=model&sort_direction=asc"))
+                        :data
+                        (map (juxt :model :name))))))
+          (testing "sort direction desc"
+            (is (= [["card" "AA"] ["card" "ZZ"] ["pulse" "AA"] ["pulse" "ZZ"] ["dashboard" "AA"] ["dashboard" "ZZ"]]
+                   (->> (mt/user-http-request :rasta :get 200 (str "collection/" collection-id "/items?sort_column=model&sort_direction=desc"))
+                        :data
+                        (map (juxt :model :name)))))))))))
 
 (deftest snippet-collection-items-test
   (testing "GET /api/collection/:id/items"
@@ -602,11 +654,11 @@
              (with-some-children-of-collection nil
                (mt/user-http-request :crowberto :get 200 "collection/root")))))
     (testing "Make sure you can see everything for Users that can see everything"
-      (is (= [(default-item {:name "Electro-Magnetic Pulse", :model "pulse"})
-              (default-item {:name "Birthday Card", :description nil, :favorite false, :model "card", :display "table"})
+      (is (= [(default-item {:name "Birthday Card", :description nil, :favorite false, :model "card", :display "table"})
               (collection-item "Crowberto Corv's Personal Collection")
               (default-item {:name "Dine & Dashboard",
-                             :favorite false, :description nil, :model "dashboard"}) ]
+                             :favorite false, :description nil, :model "dashboard"})
+              (default-item {:name "Electro-Magnetic Pulse", :model "pulse"}) ]
              (with-some-children-of-collection nil
                (-> (:data (mt/user-http-request :crowberto :get 200 "collection/root/items"))
                    (remove-non-test-items &ids)
@@ -636,9 +688,9 @@
             (mt/with-temp* [PermissionsGroup           [group]
                             PermissionsGroupMembership [_ {:user_id (mt/user->id :rasta), :group_id (u/the-id group)}]]
               (perms/grant-permissions! group (perms/collection-read-path {:metabase.models.collection.root/is-root? true}))
-              (is (= [(default-item {:name "Electro-Magnetic Pulse", :model "pulse"})
-                      (default-item {:name "Birthday Card", :description nil, :favorite false, :model "card", :display "table"})
+              (is (= [(default-item {:name "Birthday Card", :description nil, :favorite false, :model "card", :display "table"})
                       (default-item {:name "Dine & Dashboard", :description nil, :favorite false, :model "dashboard"})
+                      (default-item {:name "Electro-Magnetic Pulse", :model "pulse"})
                       (collection-item "Rasta Toucan's Personal Collection")]
                      (-> (:data (mt/user-http-request :rasta :get 200 "collection/root/items"))
                          (remove-non-test-items &ids)