<commit_before>(ns metabase.api.org-test
  (:require [expectations :refer :all]
            [metabase.db :refer :all]
            [metabase.http-client :as http]
            [metabase.middleware.auth :as auth]
            (metabase.models [org :refer [Org]]
                             [org-perm :refer [OrgPerm]])
            [metabase.test-data :refer :all]
            [metabase.test-data.create :refer [create-user]]
            [metabase.test.util :refer [match-$ random-name expect-eval-actual-first]]))

;; Helper Fns

(defn create-org [org-name]
  {:pre [(string? org-name)]}
  ((user->client :crowberto) :post 200 "org" {:name org-name
                                              :slug org-name}))

;; ## /api/org/* 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 auth/response-unauthentic :body) (http/client :get 401 "org"))
(expect (get auth/response-unauthentic :body) (http/client :get 401 (format "org/%d" (:id @test-org))))


;; # GENERAL ORG ENDPOINTS

;; ## GET /api/org
;; Non-superusers should only be able to see Orgs they are members of
(let [org-name (random-name)]
  (expect-eval-actual-first
    [{:id @org-id
      :slug "test"
      :name "Test Organization"
      :description nil
      :logo_url nil
      :inherits true}]
    (do
      ;; Delete all the random test Orgs we've created
      (cascade-delete Org :id [not= (:id @test-org)])
      ;; Create a random Org so we ensure there is an Org that should NOT show up in our list
      (create-org org-name)
      ;; Now perform the API request
      ((user->client :rasta) :get 200 "org"))))

;; Superusers should be able to see all Orgs
(let [org-name (random-name)]
  (expect-eval-actual-first
      [{:id @org-id
        :slug "test"
        :name "Test Organization"
        :description nil
        :logo_url nil
        :inherits true}
       (match-$ (sel :one Org :name org-name)
         {:id $
          :slug $
          :name $
          :description nil
          :logo_url nil
          :inherits false})]
    (do
      ;; Delete all the random test Orgs we've created
      (cascade-delete Org :id [not= @org-id])
      ;; Create a random Org so we can check that we still get Orgs we're not members of
      (create-org org-name)
      ;; Now perform the API request
      ((user->client :crowberto) :get 200 "org"))))


;; ## POST /api/org
;; Check that non-superusers can't create Orgs
(expect "You don't have permissions to do that."
  (let [org-name (random-name)]
    ((user->client :rasta) :post 403 "org" {:name org-name
                                            :slug org-name})))

;; Check that superusers *can* create Orgs
(let [org-name (random-name)]
  (expect-eval-actual-first
    (match-$ (sel :one Org :name org-name)
      {:id $
       :slug org-name
       :name org-name
       :description nil
       :logo_url nil
       :inherits false})
    (create-org org-name)))

;; Test input validations on org create
(expect "'name' is a required param."
  ((user->client :crowberto) :post 400 "org" {}))

(expect "'slug' is a required param."
  ((user->client :crowberto) :post 400 "org" {:name "anything"}))


;; ## GET /api/org/:id
(expect
    {:id @org-id
     :slug "test"
     :name "Test Organization"
     :description nil
     :logo_url nil
     :inherits true}
  ((user->client :rasta) :get 200 (format "org/%d" @org-id)))

;; Check that non-superusers can't access orgs they don't have permissions to
(expect "You don't have permissions to do that."
  (let [org-name (random-name)
        my-org (create-org org-name)]
    ((user->client :rasta) :get 403 (format "org/%d" (:id my-org)))))

;; Test that invalid org id returns 404
(expect "Not found."
  ((user->client :rasta) :get 404 "org/1000"))

;; ## GET /api/org/slug/:slug
(expect
    {:id @org-id
     :slug "test"
     :name "Test Organization"
     :description nil
     :logo_url nil
     :inherits true}
  ((user->client :rasta) :get 200 (format "org/slug/%s" (:slug @test-org))))

;; Check that non-superusers can't access orgs they don't have permissions to
(expect "You don't have permissions to do that."
  (let [org-name (random-name)
        my-org (create-org org-name)]
    ((user->client :rasta) :get 403 (format "org/slug/%s" (:slug my-org)))))

;; Test that invalid org slug returns 404
(expect "Not found."
  ((user->client :rasta) :get 404 "org/slug/ksdlfkjdkfd"))


;; # MEMBERS ENDPOINTS

;; ## GET /api/org/:id/members
(expect
    #{(match-$ (user->org-perm :crowberto)
        {:id $
         :admin true
         :user_id (user->id :crowberto)
         :organization_id @org-id
         :user (match-$ (fetch-user :crowberto)
                 {:common_name "<NAME>"
                  :date_joined $
                  :last_name "Corv"
                  :id $
                  :is_superuser true
                  :last_login $
                  :first_name "Crowberto"
                  :email "<EMAIL>"})})
      (match-$ (user->org-perm :trashbird)
        {:id $
         :admin false
         :user_id (user->id :trashbird)
         :organization_id @org-id
         :user (match-$ (fetch-user :trashbird)
                 {:common_name "<NAME>"
                  :date_joined $
                  :last_name "Bird"
                  :id $
                  :is_superuser false<commit_msg>add unit test for PUT /api/org/:id<commit_after>(ns metabase.api.org-test
  (:require [expectations :refer :all]
            [metabase.db :refer :all]
            [metabase.http-client :as http]
            [metabase.middleware.auth :as auth]
            (metabase.models [org :refer [Org]]
                             [org-perm :refer [OrgPerm]])
            [metabase.test-data :refer :all]
            [metabase.test-data.create :refer [create-user]]
            [metabase.test.util :refer [match-$ random-name expect-eval-actual-first]]))

;; Helper Fns

(defn create-org [org-name]
  {:pre [(string? org-name)]}
  ((user->client :crowberto) :post 200 "org" {:name org-name
                                              :slug org-name}))

;; ## /api/org/* 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 auth/response-unauthentic :body) (http/client :get 401 "org"))
(expect (get auth/response-unauthentic :body) (http/client :get 401 (format "org/%d" (:id @test-org))))


;; # GENERAL ORG ENDPOINTS

;; ## GET /api/org
;; Non-superusers should only be able to see Orgs they are members of
(let [org-name (random-name)]
  (expect-eval-actual-first
    [{:id @org-id
      :slug "test"
      :name "Test Organization"
      :description nil
      :logo_url nil
      :inherits true}]
    (do
      ;; Delete all the random test Orgs we've created
      (cascade-delete Org :id [not= (:id @test-org)])
      ;; Create a random Org so we ensure there is an Org that should NOT show up in our list
      (create-org org-name)
      ;; Now perform the API request
      ((user->client :rasta) :get 200 "org"))))

;; Superusers should be able to see all Orgs
(let [org-name (random-name)]
  (expect-eval-actual-first
      [{:id @org-id
        :slug "test"
        :name "Test Organization"
        :description nil
        :logo_url nil
        :inherits true}
       (match-$ (sel :one Org :name org-name)
         {:id $
          :slug $
          :name $
          :description nil
          :logo_url nil
          :inherits false})]
    (do
      ;; Delete all the random test Orgs we've created
      (cascade-delete Org :id [not= @org-id])
      ;; Create a random Org so we can check that we still get Orgs we're not members of
      (create-org org-name)
      ;; Now perform the API request
      ((user->client :crowberto) :get 200 "org"))))


;; ## POST /api/org
;; Check that non-superusers can't create Orgs
(expect "You don't have permissions to do that."
  (let [org-name (random-name)]
    ((user->client :rasta) :post 403 "org" {:name org-name
                                            :slug org-name})))

;; Check that superusers *can* create Orgs
(let [org-name (random-name)]
  (expect-eval-actual-first
    (match-$ (sel :one Org :name org-name)
      {:id $
       :slug org-name
       :name org-name
       :description nil
       :logo_url nil
       :inherits false})
    (create-org org-name)))

;; Test input validations on org create
(expect "'name' is a required param."
  ((user->client :crowberto) :post 400 "org" {}))

(expect "'slug' is a required param."
  ((user->client :crowberto) :post 400 "org" {:name "anything"}))


;; ## GET /api/org/:id
(expect
    {:id @org-id
     :slug "test"
     :name "Test Organization"
     :description nil
     :logo_url nil
     :inherits true}
  ((user->client :rasta) :get 200 (format "org/%d" @org-id)))

;; Check that non-superusers can't access orgs they don't have permissions to
(expect "You don't have permissions to do that."
  (let [org-name (random-name)
        my-org (create-org org-name)]
    ((user->client :rasta) :get 403 (format "org/%d" (:id my-org)))))

;; Test that invalid org id returns 404
(expect "Not found."
  ((user->client :rasta) :get 404 "org/1000"))

;; ## GET /api/org/slug/:slug
(expect
    {:id @org-id
     :slug "test"
     :name "Test Organization"
     :description nil
     :logo_url nil
     :inherits true}
  ((user->client :rasta) :get 200 (format "org/slug/%s" (:slug @test-org))))

;; Check that non-superusers can't access orgs they don't have permissions to
(expect "You don't have permissions to do that."
  (let [org-name (random-name)
        my-org (create-org org-name)]
    ((user->client :rasta) :get 403 (format "org/slug/%s" (:slug my-org)))))

;; Test that invalid org slug returns 404
(expect "Not found."
  ((user->client :rasta) :get 404 "org/slug/ksdlfkjdkfd"))


;; ## PUT /api/org/:id
;; Test that we can update an Org
(expect-let [orig-name (random-name)
             upd-name (random-name)
             {:keys [id slug inherits] :as org} (create-org orig-name)]
  {:id id
   :slug slug
   :name upd-name
   :description upd-name
   :logo_url upd-name
   :inherits false}
  ;; we try setting `slug` & `inherits` which should both remain unmodified
  ((user->client :crowberto) :put 200 (format "org/%d" id) {:slug upd-name
                                                            :name upd-name
                                                            :description upd-name
                                                            :logo_url upd-name
                                                            :inherits true}))


;; # MEMBERS ENDPOINTS

;; ## GET /api/org/:id/members
(expect
    #{(match-$ (user->org-perm :crowberto)
        {:id $
         :admin true
         :user_id (user->id :crowberto)
         :organization_id @org-id
         :user (match-$ (fetch-user :crowberto)
                 {:common_name "<NAME>"
                  :date_joined $
                  :last_name "Corv"
                  :id $
                  :is_superuser true
                  :last_login $
                  :first_name "Crowberto"
                  :email "<EMAIL>"})})
      (match-$ (user->org-perm :trashbird)
        {:id $
         :admin false
         :user_id (user->id :trashbird)
         :organization_id @org-id
         :user (match-$ (fetch-user :trashbird)
                 {:common_name "<NAME>"
                  :date_joined $
                  :last_name "Bird"
                  :id $
                  :is_superuser false
{'fraction_non_alphanumeric': 0.13684839177544578, 'fraction_numerical': 0.00912891391519495, 'mean_word_length': 2.1084592946168126, 'pattern_counts': {'":': 0, '<': 9, '<?xml version=': 0, '>': 42, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 16, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '496863', 'n_tokens_mistral': 3837, 'n_tokens_neox': 3655, 'n_words': 1163}