Coverage for app / backend / src / tests / test_model_constraints.py: 96%

102 statements  

« prev     ^ index     » next       coverage.py v7.13.2, created at 2026-02-03 06:18 +0000

1import pytest 

2from sqlalchemy.exc import IntegrityError 

3from sqlalchemy.sql import func 

4 

5from couchers.db import session_scope 

6from couchers.models import ActivenessProbe, ActivenessProbeStatus, Cluster, Node, Page, PageType, PageVersion, Thread 

7from couchers.utils import create_polygon_lat_lng, to_multi 

8from tests.fixtures.db import generate_user 

9from tests.test_communities import create_1d_polygon, create_community 

10 

11 

12@pytest.fixture(autouse=True) 

13def _(testconfig): 

14 pass 

15 

16 

17def test_node_constraints(db): 

18 # check we can't have two official clusters for a given node 

19 with pytest.raises(IntegrityError) as e: 

20 with session_scope() as session: 

21 node = Node(geom=to_multi(create_1d_polygon(0, 2))) 

22 session.add(node) 

23 session.flush() 

24 cluster1 = Cluster( 

25 name="Testing community, cluster 1", 

26 description="Testing community description", 

27 parent_node_id=node.id, 

28 is_official_cluster=True, 

29 ) 

30 session.add(cluster1) 

31 cluster2 = Cluster( 

32 name="Testing community, cluster 2", 

33 description="Testing community description", 

34 parent_node_id=node.id, 

35 is_official_cluster=True, 

36 ) 

37 session.add(cluster2) 

38 assert "violates unique constraint" in str(e.value) 

39 assert "ix_clusters_owner_parent_node_id_is_official_cluster" in str(e.value) 

40 

41 

42def test_page_constraints(db): 

43 user, token = generate_user() 

44 

45 with session_scope() as session: 

46 c_id = create_community(session, 0, 2, "Root node", [user], [], None).id 

47 

48 # check we can't create a page without an owner 

49 with pytest.raises(IntegrityError) as e: 

50 with session_scope() as session: 

51 thread = Thread() 

52 session.add(thread) 

53 session.flush() 

54 page = Page( 

55 parent_node_id=c_id, 

56 # note no owner 

57 creator_user_id=user.id, 

58 type=PageType.guide, 

59 thread_id=thread.id, 

60 ) 

61 session.add(page) 

62 session.flush() 

63 session.add( 

64 PageVersion( 

65 page_id=page.id, 

66 editor_user_id=user.id, 

67 title="Title", 

68 content="Content", 

69 ) 

70 ) 

71 assert "violates check constraint" in str(e.value) 

72 assert "one_owner" in str(e.value) 

73 

74 with session_scope() as session: 

75 node = Node(geom=to_multi(create_polygon_lat_lng([[0, 0], [0, 2], [2, 2], [2, 0], [0, 0]]))) 

76 session.add(node) 

77 session.flush() 

78 cluster = Cluster( 

79 name="Testing Community", 

80 description="Description for testing community", 

81 parent_node_id=node.id, 

82 ) 

83 session.add(cluster) 

84 session.flush() 

85 cluster_parent_id = cluster.parent_node_id 

86 cluster_id = cluster.id 

87 

88 # check we can't create a page with two owners 

89 with pytest.raises(IntegrityError) as e: 

90 with session_scope() as session: 

91 thread = Thread() 

92 session.add(thread) 

93 session.flush() 

94 page = Page( 

95 parent_node_id=cluster_parent_id, 

96 creator_user_id=user.id, 

97 owner_cluster_id=cluster_id, 

98 owner_user_id=user.id, 

99 type=PageType.guide, 

100 thread_id=thread.id, 

101 ) 

102 session.add(page) 

103 session.flush() 

104 session.add( 

105 PageVersion( 

106 page_id=page.id, 

107 editor_user_id=user.id, 

108 title="Title", 

109 content="Content", 

110 ) 

111 ) 

112 assert "violates check constraint" in str(e.value) 

113 assert "one_owner" in str(e.value) 

114 

115 # main page must be owned by the right cluster 

116 with pytest.raises(IntegrityError) as e: 

117 with session_scope() as session: 

118 thread = Thread() 

119 session.add(thread) 

120 session.flush() 

121 main_page = Page( 

122 parent_node_id=cluster_parent_id, 

123 # note owner is not cluster 

124 creator_user_id=user.id, 

125 owner_user_id=user.id, 

126 type=PageType.main_page, 

127 thread_id=thread.id, 

128 ) 

129 session.add(main_page) 

130 session.flush() 

131 session.add( 

132 PageVersion( 

133 page_id=main_page.id, 

134 editor_user_id=user.id, 

135 title="Main page for the testing community", 

136 content="Empty.", 

137 ) 

138 ) 

139 assert "violates check constraint" in str(e.value) 

140 assert "main_page_owned_by_cluster" in str(e.value) 

141 

142 # can only have one main page 

143 with pytest.raises(IntegrityError) as e: 

144 with session_scope() as session: 

145 thread1 = Thread() 

146 session.add(thread1) 

147 session.flush() 

148 main_page1 = Page( 

149 parent_node_id=cluster_parent_id, 

150 creator_user_id=user.id, 

151 owner_cluster_id=cluster_id, 

152 type=PageType.main_page, 

153 thread_id=thread1.id, 

154 ) 

155 session.add(main_page1) 

156 session.flush() 

157 session.add( 

158 PageVersion( 

159 page_id=main_page1.id, 

160 editor_user_id=user.id, 

161 title="Main page 1 for the testing community", 

162 content="Empty.", 

163 ) 

164 ) 

165 thread2 = Thread() 

166 session.add(thread2) 

167 session.flush() 

168 main_page2 = Page( 

169 parent_node_id=cluster_parent_id, 

170 creator_user_id=user.id, 

171 owner_cluster_id=cluster_id, 

172 type=PageType.main_page, 

173 thread_id=thread2.id, 

174 ) 

175 session.add(main_page2) 

176 session.flush() 

177 session.add( 

178 PageVersion( 

179 page_id=main_page2.id, 

180 editor_user_id=user.id, 

181 title="Main page 2 for the testing community", 

182 content="Empty.", 

183 ) 

184 ) 

185 assert "violates unique constraint" in str(e.value) 

186 assert "ix_pages_owner_cluster_id_type" in str(e.value) 

187 

188 

189def test_activeness_probes_cant_have_multiple(db): 

190 # can't have two active activeness probes for a given user 

191 user, token = generate_user() 

192 

193 with session_scope() as session: 

194 # we can create one 

195 first_probe = ActivenessProbe(user_id=user.id) 

196 session.add(first_probe) 

197 session.commit() 

198 

199 # change it to expired 

200 first_probe.response = ActivenessProbeStatus.expired 

201 first_probe.responded = func.now() 

202 session.commit() 

203 

204 # can create another one 

205 session.add(ActivenessProbe(user_id=user.id)) 

206 session.commit() 

207 

208 # can't create one more 

209 with pytest.raises(IntegrityError) as e: 

210 with session_scope() as session: 

211 session.add(ActivenessProbe(user_id=user.id)) 

212 assert "violates unique constraint" in str(e.value)