;; This Source Code Form is subject to the terms of the Mozilla Public ;; License, v. 2.0. If a copy of the MPL was not distributed with this ;; file, You can obtain one at http://mozilla.org/MPL/2.0/. ;; ;; Copyright (c) KALEIDOS INC (ns backend-tests.rpc-comment-test (:require [app.common.geom.point :as gpt] [app.common.uuid :as uuid] [app.db :as db] [app.http :as http] [app.rpc :as-alias rpc] [app.rpc.commands.comments :as comments] [app.rpc.cond :as cond] [app.rpc.quotes :as-alias quotes] [app.util.time :as dt] [backend-tests.helpers :as th] [clojure.test :as t] [datoteka.fs :as fs] [mockery.core :refer [with-mocks]])) (t/use-fixtures :once th/state-init) (t/use-fixtures :each th/database-reset) (t/deftest comment-and-threads-crud (with-mocks [mock {:target 'app.config/get :return (th/config-get-mock {:quotes-teams-per-profile 200})}] (let [profile-1 (th/create-profile* 1 {:is-active true}) profile-2 (th/create-profile* 2 {:is-active true}) team (th/create-team* 1 {:profile-id (:id profile-1)}) ;; role (th/create-team-role* {:team-id (:id team) ;; :profile-id (:id profile-2) ;; :role :admin}) project (th/create-project* 1 {:team-id (:id team) :profile-id (:id profile-1)}) file-1 (th/create-file* 1 {:profile-id (:id profile-1) :project-id (:id project)}) file-2 (th/create-file* 2 {:profile-id (:id profile-1) :project-id (:id project)}) page-id (get-in file-1 [:data :pages 0])] (t/testing "comment thread creation" (let [data {::th/type :create-comment-thread ::rpc/profile-id (:id profile-1) :file-id (:id file-1) :page-id page-id :position (gpt/point 0) :content "hello world" :frame-id uuid/zero} out (th/command! data)] ;; (th/print-result! out) (t/is (th/success? out)) (let [result (:result out)] (t/is (uuid? (:id result))) (t/is (uuid? (:file-id result))) (t/is (uuid? (:page-id result))) (t/is (uuid? (:comment-id result))) (t/is (= (:file-id result) (:id file-1))) (t/is (= (:page-id result) page-id))))) (t/testing "comment thread status update" (let [thread (-> (th/db-query :comment-thread {:file-id (:id file-1)}) first) ;; comment (-> (th/db-query :comment {:thread-id (:id thread)}) first) data {::th/type :update-comment-thread-status ::rpc/profile-id (:id profile-1) :id (:id thread)} status (th/db-get :comment-thread-status {:thread-id (:id thread) :profile-id (:id profile-1)})] (t/is (= (:modified-at status) (:modified-at thread))) (let [{:keys [result] :as out} (th/command! data)] (t/is (th/success? out)) (t/is (dt/instant? (:modified-at result)))) (let [status' (th/db-get :comment-thread-status {:thread-id (:id thread) :profile-id (:id profile-1)})] (t/is (not= (:modified-at status') (:modified-at thread)))))) (t/testing "comment thread status update 2" (let [thread (-> (th/db-query :comment-thread {:file-id (:id file-1)}) first) data {::th/type :update-comment-thread-status ::rpc/profile-id (:id profile-2) :id (:id thread)}] (let [{:keys [error] :as out} (th/command! data)] ;; (th/print-result! out) (t/is (not (th/success? out))) (t/is (= :not-found (th/ex-type error)))))) (t/testing "update comment thread" (let [thread (-> (th/db-query :comment-thread {:file-id (:id file-1)}) first) data {::th/type :update-comment-thread ::rpc/profile-id (:id profile-1) :is-resolved true :id (:id thread)}] (t/is (false? (:is-resolved thread))) (let [{:keys [result] :as out} (th/command! data)] (t/is (th/success? out)) (t/is (nil? result))) (let [thread (th/db-get :comment-thread {:id (:id thread)})] (t/is (true? (:is-resolved thread)))))) (t/testing "create comment" (let [thread (-> (th/db-query :comment-thread {:file-id (:id file-1)}) first) data {::th/type :create-comment ::rpc/profile-id (:id profile-1) :thread-id (:id thread) :content "comment 2"}] (let [{:keys [result] :as out} (th/command! data) {:keys [modified-at]} (th/db-get :comment-thread-status {:thread-id (:id thread) :profile-id (:id profile-1)})] ;; (th/print-result! out) (t/is (th/success? out)) (t/is (uuid? (:id result))) (t/is (= (:owner-id result) (:id profile-1))) (t/is (:modified-at result) modified-at)))) (t/testing "update comment" (let [thread (-> (th/db-query :comment-thread {:file-id (:id file-1)}) first) comment (-> (th/db-query :comment {:thread-id (:id thread) :content "comment 2"}) first) data {::th/type :update-comment ::rpc/profile-id (:id profile-1) :id (:id comment) :content "comment 2 mod"}] (let [{:keys [result] :as out} (th/command! data)] ;; (th/print-result! out) (t/is (th/success? out)) (t/is (nil? result))) (let [comment' (th/db-get :comment {:id (:id comment)})] (t/is (not= (:modified-at comment) (:modified-at comment'))) (t/is (= (:content data) (:content comment')))))) (t/testing "retrieve threads" (let [data {::th/type :get-comment-threads ::rpc/profile-id (:id profile-1) :file-id (:id file-1)} out (th/command! data)] ;; (th/print-result! out) (t/is (th/success? out)) (let [[thread :as result] (:result out)] (t/is (= 1 (count result))) (t/is (= "Page 1" (:page-name thread))) (t/is (= "hello world" (:content thread))) (t/is (= 2 (:count-comments thread))) (t/is (true? (:is-resolved thread)))))) (t/testing "unread comment threads" (let [thread (-> (th/db-query :comment-thread {:file-id (:id file-1)}) first) data {::th/type :get-unread-comment-threads ::rpc/profile-id (:id profile-1)}] (let [{:keys [result] :as out} (th/command! (assoc data :team-id (:default-team-id profile-1)))] (t/is (th/success? out)) (t/is (= [] result))) (let [{:keys [error] :as out} (th/command! (assoc data :team-id (:default-team-id profile-2)))] (t/is (not (th/success? out))) (t/is (= :not-found (th/ex-type error)))) (let [{:keys [result] :as out} (th/command! (assoc data :team-id (:id team)))] ;; (th/print-result! out) (t/is (th/success? out)) (let [[thread :as result] (:result out)] (t/is (= 1 (count result))))) (let [data {::th/type :update-comment-thread-status ::rpc/profile-id (:id profile-1) :id (:id thread)} out (th/command! data)] (t/is (th/success? out))) (let [{:keys [result] :as out} (th/command! (assoc data :team-id (:id team)))] ;; (th/print-result! out) (t/is (th/success? out)) (let [result (:result out)] (t/is (= 0 (count result))))))) (t/testing "get comment thread" (let [thread (-> (th/db-query :comment-thread {:file-id (:id file-1)}) first) data {::th/type :get-comment-thread ::rpc/profile-id (:id profile-1) :file-id (:id file-1) :id (:id thread)}] (let [{:keys [result] :as out} (th/command! data)] ;; (th/print-result! out) (t/is (th/success? out)) (t/is (= (:id thread) (:id result)))))) (t/testing "get comments" (let [thread (-> (th/db-query :comment-thread {:file-id (:id file-1)}) first) data {::th/type :get-comments ::rpc/profile-id (:id profile-1) :thread-id (:id thread)} out (th/command! data)] ;; (th/print-result! out) (t/is (th/success? out)) (let [comments (:result out)] (t/is (= 2 (count comments)))))) (t/testing "get profiles" (let [data {::th/type :get-profiles-for-file-comments ::rpc/profile-id (:id profile-1) :file-id (:id file-1)} out (th/command! data)] ;; (th/print-result! out) (t/is (th/success? out)) (let [[profile :as profiles] (:result out)] (t/is (= 1 (count profiles))) (t/is (= (:id profile-1) (:id profile)))))) (t/testing "get profiles 2" (let [data {::th/type :get-profiles-for-file-comments ::rpc/profile-id (:id profile-2) :file-id (:id file-1)} out (th/command! data)] ;; (th/print-result! out) (t/is (not (th/success? out))) (t/is (= :not-found (th/ex-type (:error out)))))) (t/testing "delete comment" (let [thread (-> (th/db-query :comment-thread {:file-id (:id file-1)}) first) comment (-> (th/db-query :comment {:thread-id (:id thread) :content "comment 2 mod"}) first) data {::th/type :delete-comment ::rpc/profile-id (:id profile-2) :id (:id comment)} out (th/command! data)] ;; (th/print-result! out) (t/is (not (th/success? out))) (t/is (= :not-found (th/ex-type (:error out)))) (let [comments (th/db-query :comment {:thread-id (:id thread)})] (t/is (= 2 (count comments)))))) (t/testing "delete comment 2" (let [thread (-> (th/db-query :comment-thread {:file-id (:id file-1)}) first) comment (-> (th/db-query :comment {:thread-id (:id thread) :content "comment 2 mod"}) first) data {::th/type :delete-comment ::rpc/profile-id (:id profile-1) :id (:id comment)} out (th/command! data)] ;; (th/print-result! out) (t/is (th/success? out)) (let [comments (th/db-query :comment {:thread-id (:id thread)})] (t/is (= 1 (count comments)))))) (t/testing "delete comment thread" (let [thread (-> (th/db-query :comment-thread {:file-id (:id file-1)}) first) data {::th/type :delete-comment-thread ::rpc/profile-id (:id profile-2) :id (:id thread)} out (th/command! data)] ;; (th/print-result! out) (t/is (not (th/success? out))) (t/is (= :not-found (th/ex-type (:error out)))) (let [threads (th/db-query :comment-thread {:file-id (:id file-1)})] (t/is (= 1 (count threads)))))) (t/testing "delete comment thread 2" (let [thread (-> (th/db-query :comment-thread {:file-id (:id file-1)}) first) data {::th/type :delete-comment-thread ::rpc/profile-id (:id profile-1) :id (:id thread)} out (th/command! data)] ;; (th/print-result! out) (t/is (th/success? out)) (let [threads (th/db-query :comment-thread {:file-id (:id file-1)})] (t/is (= 0 (count threads)))))))))