1
+ package com .redis .om .spring .issues ;
2
+
3
+ import static org .assertj .core .api .Assertions .assertThat ;
4
+ import static org .junit .jupiter .api .Assertions .*;
5
+
6
+ import org .junit .jupiter .api .Test ;
7
+ import org .springframework .beans .factory .annotation .Autowired ;
8
+ import org .springframework .boot .autoconfigure .SpringBootApplication ;
9
+ import org .springframework .boot .test .context .SpringBootTest ;
10
+ import org .springframework .context .annotation .Configuration ;
11
+ import org .springframework .data .annotation .Id ;
12
+ import org .springframework .test .annotation .DirtiesContext ;
13
+ import org .testcontainers .junit .jupiter .Testcontainers ;
14
+
15
+ import com .redis .om .spring .AbstractBaseOMTest ;
16
+ import com .redis .om .spring .TestConfig ;
17
+ import com .redis .om .spring .annotations .Document ;
18
+ import com .redis .om .spring .annotations .EnableRedisDocumentRepositories ;
19
+ import com .redis .om .spring .annotations .Indexed ;
20
+ import com .redis .om .spring .indexing .RediSearchIndexer ;
21
+ import com .redis .om .spring .ops .RedisModulesOperations ;
22
+ import com .redis .om .spring .ops .search .SearchOperations ;
23
+
24
+ import redis .clients .jedis .exceptions .JedisDataException ;
25
+
26
+ /**
27
+ * Test for issue #636: "Improve indexExistsFor method in RediSearchIndexer"
28
+ *
29
+ * This test verifies that the indexExistsFor method properly handles different
30
+ * error messages from different Redis versions when checking for non-existent indexes.
31
+ */
32
+ @ Testcontainers
33
+ @ DirtiesContext
34
+ @ SpringBootTest (classes = Issue636IndexExistsTest .Config .class )
35
+ class Issue636IndexExistsTest extends AbstractBaseOMTest {
36
+
37
+ @ Autowired
38
+ RediSearchIndexer indexer ;
39
+
40
+ @ Autowired
41
+ RedisModulesOperations <String > modulesOperations ;
42
+
43
+ @ Test
44
+ void testIssue636_VerifyErrorMessageHandling () {
45
+ // Try to get info for a non-existent index to verify error handling
46
+ SearchOperations <String > searchOps = modulesOperations .opsForSearch ("non_existent_index" );
47
+
48
+ JedisDataException capturedError = null ;
49
+ try {
50
+ searchOps .getInfo ();
51
+ fail ("Expected JedisDataException for non-existent index" );
52
+ } catch (JedisDataException e ) {
53
+ capturedError = e ;
54
+ }
55
+
56
+ assertNotNull (capturedError , "Should have caught an exception" );
57
+ String errorMessage = capturedError .getMessage ();
58
+
59
+ // The fixed implementation now handles multiple error message patterns
60
+ // to support different Redis versions (Redis Stack, Redis 7.x, Redis 8.0+)
61
+ String lowerCaseMessage = errorMessage .toLowerCase ();
62
+ boolean isRecognizedError = lowerCaseMessage .contains ("unknown index" ) ||
63
+ lowerCaseMessage .contains ("no such index" ) ||
64
+ lowerCaseMessage .contains ("index does not exist" ) ||
65
+ lowerCaseMessage .contains ("not found" );
66
+
67
+ assertTrue (isRecognizedError ,
68
+ "Error message should be recognized. Actual: " + errorMessage );
69
+ }
70
+
71
+ @ Test
72
+ void testIssue636_IndexExistsForNonExistentEntity () {
73
+ // Test that indexExistsFor returns false for an entity that has no index
74
+ boolean exists = indexer .indexExistsFor (NonIndexedEntity .class );
75
+ assertFalse (exists , "Index should not exist for NonIndexedEntity" );
76
+ }
77
+
78
+ @ Test
79
+ void testIssue636_IndexExistsForIndexedEntity () {
80
+ // Create an index for TestEntity
81
+ indexer .createIndexFor (TestEntity636 .class );
82
+
83
+ // Verify it exists
84
+ boolean exists = indexer .indexExistsFor (TestEntity636 .class );
85
+ assertTrue (exists , "Index should exist after creation" );
86
+
87
+ // Drop the index
88
+ indexer .dropIndexFor (TestEntity636 .class );
89
+
90
+ // Verify it no longer exists
91
+ exists = indexer .indexExistsFor (TestEntity636 .class );
92
+ assertFalse (exists , "Index should not exist after dropping" );
93
+ }
94
+
95
+ @ Test
96
+ void testIssue636_ErrorMessageCompatibility () {
97
+ // Test that both error message patterns are handled correctly
98
+ // This simulates what the fixed method should do
99
+
100
+ String [] possibleErrorMessages = {
101
+ "ERR Unknown index name" , // Redis Stack / Redis 7.x
102
+ "ERR no such index" , // Potential Redis 8.0 message
103
+ "ERR index does not exist" , // Alternative format
104
+ "Unknown index name 'test_idx'" , // With index name included
105
+ "no such index: test_idx" // Alternative with index name
106
+ };
107
+
108
+ for (String errorMsg : possibleErrorMessages ) {
109
+ // The fixed logic should handle all these patterns
110
+ boolean shouldReturnFalse = errorMsg .toLowerCase ().contains ("unknown index" ) ||
111
+ errorMsg .toLowerCase ().contains ("no such index" ) ||
112
+ errorMsg .toLowerCase ().contains ("index does not exist" );
113
+
114
+ assertTrue (shouldReturnFalse ,
115
+ "Error message should be recognized as index not found: " + errorMsg );
116
+ }
117
+ }
118
+
119
+ // Test entities
120
+ @ Document
121
+ static class TestEntity636 {
122
+ @ Id
123
+ private String id ;
124
+
125
+ @ Indexed
126
+ private String name ;
127
+
128
+ public String getId () { return id ; }
129
+ public void setId (String id ) { this .id = id ; }
130
+ public String getName () { return name ; }
131
+ public void setName (String name ) { this .name = name ; }
132
+ }
133
+
134
+ static class NonIndexedEntity {
135
+ private String id ;
136
+ private String value ;
137
+
138
+ public String getId () { return id ; }
139
+ public void setId (String id ) { this .id = id ; }
140
+ public String getValue () { return value ; }
141
+ public void setValue (String value ) { this .value = value ; }
142
+ }
143
+
144
+ @ SpringBootApplication
145
+ @ Configuration
146
+ @ EnableRedisDocumentRepositories (
147
+ basePackages = "com.redis.om.spring.fixtures.document.repository"
148
+ )
149
+ static class Config extends TestConfig {
150
+ }
151
+ }
0 commit comments