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
« 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
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
12@pytest.fixture(autouse=True)
13def _(testconfig):
14 pass
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)
42def test_page_constraints(db):
43 user, token = generate_user()
45 with session_scope() as session:
46 c_id = create_community(session, 0, 2, "Root node", [user], [], None).id
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)
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
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)
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)
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)
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()
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()
199 # change it to expired
200 first_probe.response = ActivenessProbeStatus.expired
201 first_probe.responded = func.now()
202 session.commit()
204 # can create another one
205 session.add(ActivenessProbe(user_id=user.id))
206 session.commit()
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)