11import fs from "node:fs" ;
2+ import os from "node:os" ;
23import path from "node:path" ;
34import { beforeEach , describe , expect , it , vi } from "vitest" ;
45import type { DingTalkConfig } from "../../src/types" ;
@@ -107,6 +108,8 @@ const mockedUpsertInboundMessageContext = vi.mocked(messageContextStore.upsertIn
107108const mockedResolveByMsgId = vi . mocked ( messageContextStore . resolveByMsgId ) ;
108109const mockedResolveByAlias = vi . mocked ( messageContextStore . resolveByAlias ) ;
109110const mockedResolveByCreatedAtWindow = vi . mocked ( messageContextStore . resolveByCreatedAtWindow ) ;
111+ const TEST_TMP_DIR = fs . mkdtempSync ( path . join ( os . tmpdir ( ) , "dingtalk-media-unit-" ) ) ;
112+ const STORE_PATH = path . join ( TEST_TMP_DIR , "store.json" ) ;
110113
111114function buildRuntime ( ) {
112115 return {
@@ -124,7 +127,7 @@ function buildRuntime() {
124127 } ) ,
125128 } ,
126129 session : {
127- resolveStorePath : vi . fn ( ) . mockReturnValue ( "/tmp/store.json" ) ,
130+ resolveStorePath : vi . fn ( ) . mockReturnValue ( STORE_PATH ) ,
128131 readSessionUpdatedAt : vi . fn ( ) . mockReturnValue ( null ) ,
129132 recordInboundSession : vi . fn ( ) . mockResolvedValue ( undefined ) ,
130133 } ,
@@ -149,7 +152,7 @@ describe("inbound-handler media handling", () => {
149152 beforeEach ( ( ) => {
150153 clearTargetDirectoryStateCache ( ) ;
151154 // Use rimraf-style cleanup: retry on ENOTEMPTY
152- const stateDir = path . join ( path . dirname ( "/tmp/store.json" ) , "dingtalk-state" ) ;
155+ const stateDir = path . join ( TEST_TMP_DIR , "dingtalk-state" ) ;
153156 try {
154157 fs . rmSync ( stateDir , { recursive : true , force : true } ) ;
155158 } catch ( e ) {
@@ -625,7 +628,7 @@ describe("inbound-handler media handling", () => {
625628 {
626629 accountId : "main" ,
627630 log : undefined ,
628- storePath : "/tmp/store.json" ,
631+ storePath : STORE_PATH ,
629632 conversationId : "cid_ok" ,
630633 quotedRef : {
631634 targetDirection : "inbound" ,
0 commit comments