Coverage for databases/sync_tests/test_full_text_search.py: 100%
38 statements
« prev ^ index » next coverage.py v7.2.7, created at 2024-08-27 18:25 +0000
« prev ^ index » next coverage.py v7.2.7, created at 2024-08-27 18:25 +0000
1from typing import Optional, cast
3import pytest
4from pydantic import BaseModel
6from prisma import Prisma
8from .._types import DatabaseMapping, SupportedDatabase
11# Define a class to hold the search queries
12class FullTextSearchSyntax(BaseModel):
13 search_or: str
14 search_and: str
17# Define the queries for MySQL
18_mysql_syntax = FullTextSearchSyntax(
19 search_or='cats dogs',
20 search_and='+cats +dogs',
21)
23# Define the queries for PostgreSQL
24_postgresql_syntax = FullTextSearchSyntax(
25 search_or='cats | dogs',
26 search_and='cats & dogs',
27)
29# Map the syntax to the corresponding database
30FULL_TEXT_SEARCH_SYNTAX: DatabaseMapping[Optional[FullTextSearchSyntax]] = {
31 'mysql': _mysql_syntax,
32 'postgresql': _postgresql_syntax,
33 'cockroachdb': None,
34 'mariadb': None,
35 'sqlite': None,
36}
39def test_full_text_search(client: Prisma) -> None:
40 """Ensure that full-text search works correctly on both PostgreSQL and MySQL"""
42 # Determine the correct syntax based on the database
43 db_type = cast(SupportedDatabase, client._active_provider)
44 syntax = FULL_TEXT_SEARCH_SYNTAX[db_type]
46 if syntax is None:
47 pytest.skip(f'Skipping test for {db_type}')
49 # Create some posts with varied content
50 client.post.create_many(
51 data=[
52 {
53 'title': 'cats are great pets. dogs are loyal companions.',
54 'published': True,
55 },
56 {
57 'title': 'cats are independent and mysterious animals.',
58 'published': True,
59 },
60 {
61 'title': 'rabbits and hamsters are small and cute pets.',
62 'published': True,
63 },
64 ]
65 )
67 # Test: Search for posts that contain 'cats' or 'dogs'
68 posts = client.post.find_many(
69 where={
70 'title': {
71 'search': syntax.search_or,
72 },
73 }
74 )
75 assert len(posts) == 2
76 for post in posts:
77 assert 'cats' in post.title or 'dogs' in post.title
79 # Test: Search for posts that contain both 'cats' and 'dogs'
80 posts = client.post.find_many(
81 where={
82 'title': {
83 'search': syntax.search_and,
84 },
85 }
86 )
87 assert len(posts) == 1
88 assert 'cats' in posts[0].title
89 assert 'dogs' in posts[0].title
92def test_order_by_relevance(client: Prisma) -> None:
93 """Ensure that ordering by relevance works correctly on both PostgreSQL and MySQL"""
95 # Determine the correct syntax based on the database
96 db_type = cast(SupportedDatabase, client._active_provider)
97 syntax = FULL_TEXT_SEARCH_SYNTAX[db_type]
99 if syntax is None:
100 pytest.skip(f'Skipping test for {db_type}')
102 # Create some posts with varied content
103 client.post.create_many(
104 data=[
105 {
106 'title': 'cats are great pets. dogs are loyal companions.',
107 'published': True,
108 },
109 {
110 'title': 'cats are independent and mysterious animals.',
111 'published': True,
112 },
113 {
114 'title': 'rabbits and hamsters are small and cute pets.',
115 'published': True,
116 },
117 ]
118 )
120 # Test: Order posts by relevance descending
121 post = client.post.find_first(
122 order={
123 '_relevance': {
124 'fields': ['title'],
125 'search': syntax.search_or,
126 'sort': 'desc',
127 },
128 }
129 )
130 assert post is not None
131 assert 'cats' in post.title
132 assert 'dogs' in post.title
134 # Test: Order posts by relevance ascending
135 post = client.post.find_first(
136 order={
137 '_relevance': {
138 'fields': ['title'],
139 'search': syntax.search_or,
140 'sort': 'asc',
141 },
142 }
143 )
144 assert post is not None
145 assert 'rabbits' in post.title