mirror of
https://gitee.com/mateos/mateclaw.git
synced 2026-09-14 03:33:43 +08:00
The PRIVATE_ITEMS list contained the bare 'test' entry, which rsync interprets as 'any directory named test at any depth' — so it caught the root-level /test/ scratch directory (intended) AND every src/test/ under each module (not intended). Pattern is already anchored to /test (root-only). This commit rsyncs the accumulated src/test/ tree forward so opensource has the unit tests that have been written / updated against existing src/main/ code since the pattern regression. Going forward each per-commit sync will carry src/test/ files along with the main change.
145 lines
6.0 KiB
Java
145 lines
6.0 KiB
Java
package vip.mate.wiki.service;
|
|
|
|
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
|
|
import org.junit.jupiter.api.BeforeEach;
|
|
import org.junit.jupiter.api.DisplayName;
|
|
import org.junit.jupiter.api.Test;
|
|
import org.junit.jupiter.params.ParameterizedTest;
|
|
import org.junit.jupiter.params.provider.ValueSource;
|
|
import org.springframework.context.ApplicationEventPublisher;
|
|
import vip.mate.system.featureflag.FeatureFlagService;
|
|
import vip.mate.tool.builtin.DocumentExtractTool;
|
|
import vip.mate.tool.image.vision.ImageVisionService;
|
|
import vip.mate.wiki.WikiProperties;
|
|
import vip.mate.wiki.model.WikiRawMaterialEntity;
|
|
import vip.mate.wiki.repository.WikiRawMaterialMapper;
|
|
|
|
import static org.junit.jupiter.api.Assertions.*;
|
|
import static org.mockito.ArgumentMatchers.any;
|
|
import static org.mockito.Mockito.*;
|
|
|
|
/**
|
|
* Verifies that addText / addFile deduplication works across all processing
|
|
* statuses, not just 'completed'. A duplicate upload should always reuse
|
|
* the existing row — never insert a second one.
|
|
*/
|
|
class WikiRawMaterialDedupTest {
|
|
|
|
private WikiRawMaterialMapper rawMapper;
|
|
private WikiKnowledgeBaseService kbService;
|
|
private ApplicationEventPublisher eventPublisher;
|
|
private WikiChunkService chunkService;
|
|
private WikiRawMaterialService service;
|
|
|
|
private static final Long KB_ID = 1L;
|
|
|
|
@BeforeEach
|
|
void setUp() {
|
|
rawMapper = mock(WikiRawMaterialMapper.class);
|
|
kbService = mock(WikiKnowledgeBaseService.class);
|
|
eventPublisher = mock(ApplicationEventPublisher.class);
|
|
chunkService = mock(WikiChunkService.class);
|
|
WikiProperties props = new WikiProperties();
|
|
props.setAutoProcessOnUpload(false); // don't fire events during test
|
|
DocumentExtractTool docTool = mock(DocumentExtractTool.class);
|
|
ImageVisionService visionService = mock(ImageVisionService.class);
|
|
PdfImageExtractor pdfImageExtractor = mock(PdfImageExtractor.class);
|
|
FeatureFlagService featureFlagService = mock(FeatureFlagService.class);
|
|
|
|
service = new WikiRawMaterialService(rawMapper, kbService, props, eventPublisher, docTool,
|
|
chunkService, visionService, pdfImageExtractor, featureFlagService);
|
|
}
|
|
|
|
private WikiRawMaterialEntity existingRow(Long id, String status) {
|
|
WikiRawMaterialEntity e = new WikiRawMaterialEntity();
|
|
e.setId(id);
|
|
e.setKbId(KB_ID);
|
|
e.setTitle("test.pdf");
|
|
e.setProcessingStatus(status);
|
|
e.setContentHash("abc123");
|
|
return e;
|
|
}
|
|
|
|
// ==================== addText dedup ====================
|
|
|
|
@ParameterizedTest(name = "addText dedup when existing status = {0}")
|
|
@ValueSource(strings = {"completed", "partial", "failed", "pending", "processing"})
|
|
@DisplayName("addText: same hash should reuse existing row regardless of status")
|
|
void addText_dedup_all_statuses(String status) {
|
|
WikiRawMaterialEntity existing = existingRow(42L, status);
|
|
when(rawMapper.selectOne(any(LambdaQueryWrapper.class))).thenReturn(existing);
|
|
// reprocess() calls selectById internally for partial/failed
|
|
when(rawMapper.selectById(42L)).thenReturn(existing);
|
|
|
|
WikiRawMaterialEntity result = service.addText(KB_ID, "test", "some content");
|
|
|
|
assertEquals(42L, result.getId(), "should return existing id");
|
|
// Should never insert a new row
|
|
verify(rawMapper, never()).insert(any(WikiRawMaterialEntity.class));
|
|
}
|
|
|
|
@Test
|
|
@DisplayName("addText: reprocess triggered for partial status")
|
|
void addText_dedup_partial_triggers_reprocess() {
|
|
WikiRawMaterialEntity existing = existingRow(42L, "partial");
|
|
// First call: dedup lookup returns existing
|
|
// Second call (inside reprocess): selectById returns existing
|
|
when(rawMapper.selectOne(any(LambdaQueryWrapper.class))).thenReturn(existing);
|
|
when(rawMapper.selectById(42L)).thenReturn(existing);
|
|
|
|
service.addText(KB_ID, "test", "some content");
|
|
|
|
// reprocess changes status to pending and fires event
|
|
assertEquals("pending", existing.getProcessingStatus());
|
|
verify(eventPublisher).publishEvent(any());
|
|
}
|
|
|
|
@Test
|
|
@DisplayName("addText: reprocess triggered for failed status")
|
|
void addText_dedup_failed_triggers_reprocess() {
|
|
WikiRawMaterialEntity existing = existingRow(42L, "failed");
|
|
when(rawMapper.selectOne(any(LambdaQueryWrapper.class))).thenReturn(existing);
|
|
when(rawMapper.selectById(42L)).thenReturn(existing);
|
|
|
|
service.addText(KB_ID, "test", "some content");
|
|
|
|
assertEquals("pending", existing.getProcessingStatus());
|
|
verify(eventPublisher).publishEvent(any());
|
|
}
|
|
|
|
@Test
|
|
@DisplayName("addText: completed status returns as-is, no reprocess")
|
|
void addText_dedup_completed_no_reprocess() {
|
|
WikiRawMaterialEntity existing = existingRow(42L, "completed");
|
|
when(rawMapper.selectOne(any(LambdaQueryWrapper.class))).thenReturn(existing);
|
|
|
|
WikiRawMaterialEntity result = service.addText(KB_ID, "test", "some content");
|
|
|
|
assertEquals("completed", result.getProcessingStatus());
|
|
verify(eventPublisher, never()).publishEvent(any());
|
|
}
|
|
|
|
@Test
|
|
@DisplayName("addText: pending/processing status returns as-is, no reprocess")
|
|
void addText_dedup_pending_no_reprocess() {
|
|
WikiRawMaterialEntity existing = existingRow(42L, "pending");
|
|
when(rawMapper.selectOne(any(LambdaQueryWrapper.class))).thenReturn(existing);
|
|
|
|
WikiRawMaterialEntity result = service.addText(KB_ID, "test", "some content");
|
|
|
|
assertEquals("pending", result.getProcessingStatus());
|
|
verify(eventPublisher, never()).publishEvent(any());
|
|
}
|
|
|
|
@Test
|
|
@DisplayName("addText: no existing row inserts new record")
|
|
void addText_no_duplicate_inserts() {
|
|
when(rawMapper.selectOne(any(LambdaQueryWrapper.class))).thenReturn(null);
|
|
|
|
service.addText(KB_ID, "test", "brand new content");
|
|
|
|
verify(rawMapper).insert(any(WikiRawMaterialEntity.class));
|
|
verify(kbService).incrementRawCount(KB_ID);
|
|
}
|
|
}
|