55
66import { DeviceEventEmitter } from 'react-native' ;
77
8- import { Navigation } from '@constants' ;
8+ import { ActionType , Events , Navigation } from '@constants' ;
99import { SYSTEM_IDENTIFIERS } from '@constants/database' ;
1010import DatabaseManager from '@database/manager' ;
1111import { getMyChannel } from '@queries/servers/channel' ;
12+ import { getPostById } from '@queries/servers/post' ;
1213import { getCommonSystemValues , getTeamHistory } from '@queries/servers/system' ;
1314import { getTeamChannelHistory } from '@queries/servers/team' ;
1415import { dismissAllModalsAndPopToRoot , dismissAllModalsAndPopToScreen } from '@screens/navigation' ;
16+ import TestHelper from '@test/test_helper' ;
1517
1618import {
1719 switchToChannel ,
@@ -27,6 +29,8 @@ import {
2729 updateChannelsDisplayName ,
2830 showUnreadChannelsOnly ,
2931 updateDmGmDisplayName ,
32+ deletePostsForChannelsWithAutotranslation ,
33+ deletePostsForChannel ,
3034} from './channel' ;
3135
3236import type { ChannelModel , MyChannelModel , SystemModel } from '@database/models/server' ;
@@ -770,19 +774,19 @@ describe('updateMyChannelFromWebsocket', () => {
770774 const serverUrl = 'baseHandler.test.com' ;
771775 const channelId = 'id1' ;
772776 const teamId = 'tId1' ;
773- const channel : Channel = {
777+ const channel : Channel = TestHelper . fakeChannel ( {
774778 id : channelId ,
775779 team_id : teamId ,
776780 total_msg_count : 0 ,
777781 delete_at : 0 ,
778- } as Channel ;
779- const channelMember : ChannelMembership = {
782+ } ) ;
783+ const channelMember : ChannelMembership = TestHelper . fakeChannelMember ( {
780784 id : 'id' ,
781785 user_id : 'userid' ,
782786 channel_id : channelId ,
783787 msg_count : 0 ,
784788 roles : '' ,
785- } as ChannelMembership ;
789+ } ) ;
786790
787791 beforeEach ( async ( ) => {
788792 await DatabaseManager . init ( [ serverUrl ] ) ;
@@ -808,6 +812,27 @@ describe('updateMyChannelFromWebsocket', () => {
808812 expect ( model ) . toBeDefined ( ) ;
809813 expect ( model ?. roles ) . toBe ( 'channel_user' ) ;
810814 } ) ;
815+
816+ it ( 'calls deletePostsForChannel when autotranslation changes' , async ( ) => {
817+ const post = TestHelper . fakePost ( { id : 'postid1' , channel_id : channelId , root_id : '' } ) ;
818+ await operator . handleMyChannel ( { channels : [ channel ] , myChannels : [ channelMember ] , prepareRecordsOnly : false } ) ;
819+ await operator . handleChannel ( { channels : [ channel ] , prepareRecordsOnly : false } ) ;
820+ await operator . handlePosts ( { actionType : ActionType . POSTS . RECEIVED_IN_CHANNEL , order : [ post . id ] , posts : [ post ] , prepareRecordsOnly : false } ) ;
821+
822+ await updateMyChannelFromWebsocket ( serverUrl , { ...channelMember , autotranslation_disabled : true } , false ) ;
823+
824+ expect ( DeviceEventEmitter . emit ) . toHaveBeenCalledWith ( Events . POST_DELETED_FOR_CHANNEL , { serverUrl, channelId} ) ;
825+ } ) ;
826+
827+ it ( 'updates member autotranslation from channelMember' , async ( ) => {
828+ await operator . handleMyChannel ( { channels : [ channel ] , myChannels : [ channelMember ] , prepareRecordsOnly : false } ) ;
829+ await operator . handleChannel ( { channels : [ channel ] , prepareRecordsOnly : false } ) ;
830+
831+ await updateMyChannelFromWebsocket ( serverUrl , { ...channelMember , autotranslation_disabled : true } , false ) ;
832+
833+ const member = await getMyChannel ( operator . database , channelId ) ;
834+ expect ( member ?. autotranslationDisabled ) . toBe ( true ) ;
835+ } ) ;
811836} ) ;
812837
813838describe ( 'updateChannelInfoFromChannel' , ( ) => {
@@ -1133,3 +1158,186 @@ describe('updateDmGmDisplayName', () => {
11331158 expect ( ( channels ! [ 1 ] as ChannelModel ) . displayName ) . toBe ( `${ user2 . username } , ${ user3 . username } ` ) ;
11341159 } ) ;
11351160} ) ;
1161+
1162+ describe ( 'deletePostsForChannel' , ( ) => {
1163+ const serverUrl = 'baseHandler.test.com' ;
1164+ let operator : ServerDataOperator ;
1165+
1166+ const channelId = 'channelid1' ;
1167+ const teamId = 'tId1' ;
1168+ const channel : Channel = TestHelper . fakeChannel ( {
1169+ id : channelId ,
1170+ team_id : teamId ,
1171+ total_msg_count : 0 ,
1172+ } ) ;
1173+ const channelMember : ChannelMembership = TestHelper . fakeChannelMember ( {
1174+ id : 'id' ,
1175+ channel_id : channelId ,
1176+ msg_count : 0 ,
1177+ } ) ;
1178+
1179+ beforeEach ( async ( ) => {
1180+ await DatabaseManager . init ( [ serverUrl ] ) ;
1181+ operator = DatabaseManager . serverDatabases [ serverUrl ] ! . operator ;
1182+ } ) ;
1183+
1184+ afterEach ( async ( ) => {
1185+ await DatabaseManager . destroyServerDatabase ( serverUrl ) ;
1186+ } ) ;
1187+
1188+ it ( 'handle not found database' , async ( ) => {
1189+ const { models, error} = await deletePostsForChannel ( 'foo' , channelId ) ;
1190+ expect ( models ) . toEqual ( [ ] ) ;
1191+ expect ( error ) . toBeTruthy ( ) ;
1192+ } ) ;
1193+
1194+ it ( 'channel not found' , async ( ) => {
1195+ const { models, error} = await deletePostsForChannel ( serverUrl , 'nonexistent' ) ;
1196+ expect ( models ) . toEqual ( [ ] ) ;
1197+ expect ( error ) . toBeFalsy ( ) ;
1198+ } ) ;
1199+
1200+ it ( 'channel with no posts' , async ( ) => {
1201+ await operator . handleChannel ( { channels : [ channel ] , prepareRecordsOnly : false } ) ;
1202+ await operator . handleMyChannel ( { channels : [ channel ] , myChannels : [ channelMember ] , prepareRecordsOnly : false } ) ;
1203+
1204+ const { models, error} = await deletePostsForChannel ( serverUrl , channelId ) ;
1205+ expect ( models ) . toEqual ( [ ] ) ;
1206+ expect ( error ) . toBeFalsy ( ) ;
1207+ } ) ;
1208+
1209+ it ( 'channel with posts - batch written and event emitted' , async ( ) => {
1210+ const post = TestHelper . fakePost ( { id : 'postid1' , channel_id : channelId , root_id : '' } ) ;
1211+ await operator . handleChannel ( { channels : [ channel ] , prepareRecordsOnly : false } ) ;
1212+ await operator . handleMyChannel ( { channels : [ channel ] , myChannels : [ channelMember ] , prepareRecordsOnly : false } ) ;
1213+ await operator . handlePosts ( {
1214+ actionType : ActionType . POSTS . RECEIVED_IN_CHANNEL ,
1215+ order : [ post . id ] ,
1216+ posts : [ post ] ,
1217+ prepareRecordsOnly : false ,
1218+ } ) ;
1219+
1220+ const listener = jest . fn ( ) ;
1221+ const subscription = DeviceEventEmitter . addListener ( Events . POST_DELETED_FOR_CHANNEL , listener ) ;
1222+
1223+ const { models, error} = await deletePostsForChannel ( serverUrl , channelId ) ;
1224+ subscription . remove ( ) ;
1225+
1226+ expect ( error ) . toBeFalsy ( ) ;
1227+ expect ( models . length ) . toBeGreaterThan ( 0 ) ;
1228+ expect ( listener ) . toHaveBeenCalledTimes ( 1 ) ;
1229+ expect ( listener ) . toHaveBeenCalledWith ( { serverUrl, channelId} ) ;
1230+
1231+ const myChannel = await getMyChannel ( operator . database , channelId ) ;
1232+ expect ( myChannel ?. lastFetchedAt ) . toBe ( 0 ) ;
1233+ } ) ;
1234+
1235+ it ( 'prepareRecordsOnly true - no write and no emit' , async ( ) => {
1236+ const post = TestHelper . fakePost ( { id : 'postid2' , channel_id : channelId , root_id : '' } ) ;
1237+ await operator . handleChannel ( { channels : [ channel ] , prepareRecordsOnly : false } ) ;
1238+ await operator . handleMyChannel ( { channels : [ channel ] , myChannels : [ channelMember ] , prepareRecordsOnly : false } ) ;
1239+ await operator . handlePosts ( {
1240+ actionType : ActionType . POSTS . RECEIVED_IN_CHANNEL ,
1241+ order : [ post . id ] ,
1242+ posts : [ post ] ,
1243+ prepareRecordsOnly : false ,
1244+ } ) ;
1245+
1246+ const listener = jest . fn ( ) ;
1247+ const subscription = DeviceEventEmitter . addListener ( Events . POST_DELETED_FOR_CHANNEL , listener ) ;
1248+
1249+ const { models, error} = await deletePostsForChannel ( serverUrl , channelId , true ) ;
1250+ subscription . remove ( ) ;
1251+
1252+ expect ( error ) . toBeFalsy ( ) ;
1253+ expect ( models . length ) . toBeGreaterThan ( 0 ) ;
1254+ expect ( listener ) . not . toHaveBeenCalled ( ) ;
1255+
1256+ const myChannel = await getMyChannel ( operator . database , channelId ) ;
1257+ expect ( myChannel ?. _preparedState ) . toBe ( 'update' ) ;
1258+
1259+ // Batch the records to avoid the invariant error
1260+ await operator . batchRecords ( [ ...models ] , 'test' ) ;
1261+ } ) ;
1262+ } ) ;
1263+
1264+ describe ( 'deletePostsForChannelsWithAutotranslation' , ( ) => {
1265+ const serverUrl = 'baseHandler.test.com' ;
1266+ let operator : ServerDataOperator ;
1267+
1268+ const channelId = 'channelid1' ;
1269+ const teamId = 'tId1' ;
1270+ const channel : Channel = TestHelper . fakeChannel ( {
1271+ id : channelId ,
1272+ team_id : teamId ,
1273+ total_msg_count : 0 ,
1274+ autotranslation : true ,
1275+ } ) ;
1276+
1277+ beforeEach ( async ( ) => {
1278+ await DatabaseManager . init ( [ serverUrl ] ) ;
1279+ operator = DatabaseManager . serverDatabases [ serverUrl ] ! . operator ;
1280+ } ) ;
1281+
1282+ afterEach ( async ( ) => {
1283+ await DatabaseManager . destroyServerDatabase ( serverUrl ) ;
1284+ } ) ;
1285+
1286+ it ( 'no myChannels with autotranslation - no deletes' , async ( ) => {
1287+ const channelMember : ChannelMembership = TestHelper . fakeChannelMember ( {
1288+ id : 'id' ,
1289+ channel_id : channelId ,
1290+ msg_count : 0 ,
1291+ autotranslation_disabled : true ,
1292+ } ) ;
1293+ const post = TestHelper . fakePost ( { id : 'postid1' , channel_id : channelId , root_id : '' } ) ;
1294+ await operator . handleChannel ( { channels : [ channel ] , prepareRecordsOnly : false } ) ;
1295+ await operator . handleMyChannel ( { channels : [ channel ] , myChannels : [ channelMember ] , prepareRecordsOnly : false } ) ;
1296+ await operator . handlePosts ( {
1297+ actionType : ActionType . POSTS . RECEIVED_IN_CHANNEL ,
1298+ order : [ post . id ] ,
1299+ posts : [ post ] ,
1300+ prepareRecordsOnly : false ,
1301+ } ) ;
1302+
1303+ const { models, error} = await deletePostsForChannelsWithAutotranslation ( serverUrl ) ;
1304+ expect ( error ) . toBeUndefined ( ) ;
1305+ expect ( models ) . toEqual ( [ ] ) ;
1306+
1307+ const databasePost = await getPostById ( operator . database , post . id ) ;
1308+ expect ( databasePost ) . toBeDefined ( ) ;
1309+ } ) ;
1310+
1311+ it ( 'myChannels with autotranslation - delete posts' , async ( ) => {
1312+ const channelMember : ChannelMembership = TestHelper . fakeChannelMember ( {
1313+ id : 'id' ,
1314+ channel_id : channelId ,
1315+ msg_count : 0 ,
1316+ autotranslation_disabled : false ,
1317+ } ) ;
1318+ const post = TestHelper . fakePost ( { id : 'postid1' , channel_id : channelId , root_id : '' } ) ;
1319+ await operator . handleChannel ( { channels : [ channel ] , prepareRecordsOnly : false } ) ;
1320+ await operator . handleMyChannel ( { channels : [ channel ] , myChannels : [ channelMember ] , prepareRecordsOnly : false } ) ;
1321+ await operator . handlePosts ( {
1322+ actionType : ActionType . POSTS . RECEIVED_IN_CHANNEL ,
1323+ order : [ post . id ] ,
1324+ posts : [ post ] ,
1325+ prepareRecordsOnly : false ,
1326+ } ) ;
1327+
1328+ const { models, error} = await deletePostsForChannelsWithAutotranslation ( serverUrl ) ;
1329+ expect ( error ) . toBeUndefined ( ) ;
1330+ expect ( models . length ) . toBeGreaterThan ( 0 ) ;
1331+ const databasePost = await getPostById ( operator . database , post . id ) ;
1332+ expect ( databasePost ) . toBeUndefined ( ) ;
1333+ } ) ;
1334+
1335+ it ( 'handle error' , async ( ) => {
1336+ jest . spyOn ( DatabaseManager , 'getServerDatabaseAndOperator' ) . mockImplementationOnce ( ( ) => {
1337+ throw new Error ( 'DB error' ) ;
1338+ } ) ;
1339+ const { models, error} = await deletePostsForChannelsWithAutotranslation ( serverUrl ) ;
1340+ expect ( models ) . toEqual ( [ ] ) ;
1341+ expect ( error ) . toBeTruthy ( ) ;
1342+ } ) ;
1343+ } ) ;
0 commit comments