@@ -16,7 +16,7 @@ import {
16
16
} from "tests/integration/helpers/seed"
17
17
18
18
import { createCallerFactory } from "~/server/trpc"
19
- import { AuditLogEvent , db , ResourceType } from "../../database"
19
+ import { AuditLogEvent , db , ResourceState , ResourceType } from "../../database"
20
20
import { folderRouter } from "../folder.router"
21
21
22
22
const createCaller = createCallerFactory ( folderRouter )
@@ -737,6 +737,198 @@ describe("folder.router", async () => {
737
737
expect ( auditLogs ?. eventType ) . toEqual ( AuditLogEvent . ResourceUpdate )
738
738
} )
739
739
} )
740
+ describe ( "listChildPages" , ( ) => {
741
+ it ( "should throw 401 if not logged in" , async ( ) => {
742
+ // Arrange
743
+ const { folder, site } = await setupFolder ( )
744
+ const { page : indexPage } = await setupPageResource ( {
745
+ parentId : folder . id ,
746
+ siteId : site . id ,
747
+ resourceType : "IndexPage" ,
748
+ } )
749
+ await createChildPages ( {
750
+ parentId : folder . id ,
751
+ siteId : site . id ,
752
+ numPages : 3 ,
753
+ numFolders : 5 ,
754
+ } )
755
+
756
+ // Act
757
+ const result = unauthedCaller . listChildPages ( {
758
+ siteId : String ( site . id ) ,
759
+ indexPageId : indexPage . id ,
760
+ } )
761
+
762
+ // Assert
763
+ await expect ( result ) . rejects . toThrowError (
764
+ new TRPCError ( { code : "UNAUTHORIZED" } ) ,
765
+ )
766
+ await expect (
767
+ db . selectFrom ( "AuditLog" ) . selectAll ( ) . execute ( ) ,
768
+ ) . resolves . toHaveLength ( 0 )
769
+ } )
770
+
771
+ it ( "should return an empty array if `siteId` does not exist" , async ( ) => {
772
+ // Arrange
773
+ const invalidSiteId = 999
774
+ const { site, folder } = await setupFolder ( )
775
+ await setupAdminPermissions ( {
776
+ userId : session . userId ,
777
+ siteId : site . id ,
778
+ } )
779
+ expect ( site . id ) . not . toEqual ( invalidSiteId )
780
+ const { page : indexPage } = await setupPageResource ( {
781
+ parentId : folder . id ,
782
+ siteId : site . id ,
783
+ resourceType : "IndexPage" ,
784
+ } )
785
+ await createChildPages ( {
786
+ parentId : folder . id ,
787
+ siteId : site . id ,
788
+ numPages : 3 ,
789
+ numFolders : 5 ,
790
+ } )
791
+
792
+ // Act
793
+ const result = await caller . listChildPages ( {
794
+ siteId : String ( site . id ) ,
795
+ indexPageId : indexPage . id ,
796
+ } )
797
+
798
+ // Assert
799
+ expect ( result . childPages ) . toEqual ( [ ] )
800
+ } )
801
+
802
+ it ( "should throw 403 if user does not have access to the site" , async ( ) => {
803
+ // Arrange
804
+ const { site, folder } = await setupFolder ( )
805
+ const { page : indexPage } = await setupPageResource ( {
806
+ parentId : folder . id ,
807
+ siteId : site . id ,
808
+ resourceType : "IndexPage" ,
809
+ } )
810
+
811
+ // Act
812
+ const result = caller . listChildPages ( {
813
+ siteId : String ( site . id ) ,
814
+ indexPageId : indexPage . id ,
815
+ } )
816
+
817
+ // Assert
818
+ await expect ( result ) . rejects . toThrowError (
819
+ new TRPCError ( {
820
+ code : "NOT_FOUND" ,
821
+ message :
822
+ "You do not have sufficient permissions to perform this action" ,
823
+ } ) ,
824
+ )
825
+ await expect (
826
+ db . selectFrom ( "AuditLog" ) . selectAll ( ) . execute ( ) ,
827
+ ) . resolves . toHaveLength ( 0 )
828
+ } )
829
+
830
+ it ( "should throw 404 if the page specified by `indexPageId` is not an `IndexPage`" , async ( ) => {
831
+ // Arrange
832
+ const { site, folder } = await setupFolder ( )
833
+ await setupAdminPermissions ( { siteId : site . id , userId : session . userId } )
834
+ const { page } = await setupPageResource ( {
835
+ resourceType : "Page" ,
836
+ parentId : folder . id ,
837
+ } )
838
+
839
+ // Act
840
+
841
+ const result = caller . listChildPages ( {
842
+ siteId : String ( site . id ) ,
843
+ indexPageId : page . id ,
844
+ } )
845
+
846
+ // Assert
847
+ await expect ( result ) . rejects . toThrowError (
848
+ new TRPCError ( {
849
+ code : "NOT_FOUND" ,
850
+ message : "No index page with the specified id could be found" ,
851
+ } ) ,
852
+ )
853
+ await expect (
854
+ db . selectFrom ( "AuditLog" ) . selectAll ( ) . execute ( ) ,
855
+ ) . resolves . toHaveLength ( 0 )
856
+ } )
857
+
858
+ it ( "should throw 404 if the `indexPageId` does not exist" , async ( ) => {
859
+ // Arrange
860
+ const { site } = await setupFolder ( )
861
+ await setupAdminPermissions ( { siteId : site . id , userId : session . userId } )
862
+
863
+ // Act
864
+ const result = caller . listChildPages ( {
865
+ siteId : String ( site . id ) ,
866
+ indexPageId : "1234" ,
867
+ } )
868
+
869
+ // Assert
870
+ await expect ( result ) . rejects . toThrowError (
871
+ new TRPCError ( {
872
+ code : "NOT_FOUND" ,
873
+ message : "No index page with the specified id could be found" ,
874
+ } ) ,
875
+ )
876
+ await expect (
877
+ db . selectFrom ( "AuditLog" ) . selectAll ( ) . execute ( ) ,
878
+ ) . resolves . toHaveLength ( 0 )
879
+ } )
880
+
881
+ it ( "should return only the published pages of the parent folder" , async ( ) => {
882
+ // Arrange
883
+ const { site, folder } = await setupFolder ( )
884
+ await setupAdminPermissions ( { siteId : site . id , userId : session . userId } )
885
+ const { page : indexPage } = await setupPageResource ( {
886
+ parentId : folder . id ,
887
+ siteId : site . id ,
888
+ resourceType : "IndexPage" ,
889
+ } )
890
+ const { pages, folders } = await createChildPages ( {
891
+ parentId : folder . id ,
892
+ siteId : site . id ,
893
+ numPages : 3 ,
894
+ numFolders : 4 ,
895
+ state : "Published" ,
896
+ userId : session . userId ,
897
+ } )
898
+
899
+ // NOTE: Not `published`
900
+ await createChildPages ( {
901
+ parentId : folder . id ,
902
+ siteId : site . id ,
903
+ numPages : 3 ,
904
+ numFolders : 4 ,
905
+ } )
906
+
907
+ // Act
908
+ const result = await caller . listChildPages ( {
909
+ siteId : String ( site . id ) ,
910
+ indexPageId : indexPage . id ,
911
+ } )
912
+
913
+ // Assert
914
+ expect ( result . childPages ) . toHaveLength ( 7 )
915
+ const indexPagesOfFolders = await db
916
+ . selectFrom ( "Resource" )
917
+ . where (
918
+ "parentId" ,
919
+ "in" ,
920
+ folders . map ( ( { id } ) => id ) ,
921
+ )
922
+ . where ( "type" , "=" , "IndexPage" )
923
+ . select ( "id" )
924
+ . execute ( )
925
+ const indexPagesId = indexPagesOfFolders . map ( ( { id } ) => id )
926
+ const pagesId = pages . map ( ( { id } ) => id )
927
+ expect ( result . childPages . map ( ( { id } ) => id ) . toSorted ( ) ) . toStrictEqual (
928
+ [ ...pagesId , ...indexPagesId ] . toSorted ( ) ,
929
+ )
930
+ } )
931
+ } )
740
932
} )
741
933
742
934
// Test util functions
@@ -755,3 +947,69 @@ const getFolderWithPermalink = ({
755
947
. selectAll ( )
756
948
. executeTakeFirstOrThrow ( )
757
949
}
950
+
951
+ const createChildPages = async ( {
952
+ parentId,
953
+ siteId,
954
+ numPages,
955
+ numFolders,
956
+ state = ResourceState . Draft ,
957
+ userId,
958
+ } : {
959
+ parentId : string
960
+ siteId : number
961
+ numPages : number
962
+ numFolders : number
963
+ state ?: ResourceState
964
+ userId ?: string
965
+ } ) => {
966
+ if ( state === ResourceState . Published && ! userId ) {
967
+ throw new Error (
968
+ "Precondition failed for `createChildPages`: a valid `userId` is required in order to publish a resource" ,
969
+ )
970
+ }
971
+
972
+ const pages = await Promise . all (
973
+ Array . from ( { length : numPages } )
974
+ . fill ( null )
975
+ . map ( async ( ) => {
976
+ const permalink = crypto . randomUUID ( )
977
+ const { page } = await setupPageResource ( {
978
+ resourceType : "Page" ,
979
+ siteId,
980
+ parentId,
981
+ state,
982
+ permalink,
983
+ userId,
984
+ } )
985
+ return page
986
+ } ) ,
987
+ )
988
+
989
+ const folders = await Promise . all (
990
+ Array . from ( { length : numFolders } )
991
+ . fill ( null )
992
+ . map ( async ( ) => {
993
+ const { folder } = await setupFolder ( {
994
+ siteId,
995
+ parentId,
996
+ permalink : crypto . randomUUID ( ) ,
997
+ state : ResourceState . Published ,
998
+ } )
999
+
1000
+ const permalink = crypto . randomUUID ( )
1001
+ await setupPageResource ( {
1002
+ resourceType : "IndexPage" ,
1003
+ siteId,
1004
+ parentId : folder . id ,
1005
+ state,
1006
+ permalink,
1007
+ userId,
1008
+ } )
1009
+
1010
+ return folder
1011
+ } ) ,
1012
+ )
1013
+
1014
+ return { pages, folders }
1015
+ }
0 commit comments