@@ -74,6 +74,106 @@ describe('ServerSidePurge', () => {
7474 } ) ;
7575 } ) ;
7676
77+ describe ( 'getPurgeUpdates' , ( ) => {
78+ it ( 'should return empty when purge state is unchanged' , ( ) => {
79+ const groups = { c1 : { contact : { _id : 'c1' } } } ;
80+ const ids = [ 'r1' ] ;
81+ const alreadyPurged = { 'r1' : '1-rev' , 'c1' : '2-rev' } ;
82+ const toPurge = { 'r1' : true , 'c1' : true } ;
83+ const res = service . __get__ ( 'getPurgeUpdates' ) ( groups , ids , alreadyPurged , toPurge ) ;
84+ chai . expect ( res ) . to . deep . equal ( [ ] ) ;
85+ } ) ;
86+
87+ it ( 'should create docs for state changes including deletions' , ( ) => {
88+ const groups = { c1 : { contact : { _id : 'c1' } } } ;
89+ const ids = [ 'r1' , 'r2' ] ;
90+ const alreadyPurged = { 'r1' : '1-rev' , 'c1' : '2-rev' } ;
91+ const toPurge = { 'r1' : false , 'r2' : true , 'c1' : false } ;
92+ const res = service . __get__ ( 'getPurgeUpdates' ) ( groups , ids , alreadyPurged , toPurge ) ;
93+ chai . expect ( res ) . to . have . deep . members ( [
94+ { _id : 'purged:r1' , _rev : '1-rev' , _deleted : true } , // toggled off -> delete
95+ { _id : 'purged:r2' , _deleted : false } , // new purge -> create
96+ { _id : 'purged:c1' , _rev : '2-rev' , _deleted : true } , // group id appears via groups keys
97+ ] ) ;
98+ } ) ;
99+ } ) ;
100+
101+ describe ( 'bulkDocs' , ( ) => {
102+ it ( 'should filter invalid docs and strip fields, and return results' , async ( ) => {
103+ const bulkDocsStub = sinon . stub ( ) . resolves ( [
104+ { id : 'purged:r2' , rev : '3-rev' } ,
105+ ] ) ;
106+ const fakeDb = { bulkDocs : ( args ) => bulkDocsStub ( args ) } ;
107+
108+ const input = [
109+ null ,
110+ undefined ,
111+ { _id : 'purged:r1' , _deleted : true } , // no _rev -> filtered out
112+ { _id : 'purged:r2' , _rev : '2-rev' , _deleted : false } , // should remove _deleted
113+ { _id : 'purged:r3' } , // should remove empty _rev
114+ ] ;
115+
116+ const results = await service . __get__ ( 'bulkDocs' ) ( fakeDb , input ) ;
117+ chai . expect ( bulkDocsStub . callCount ) . to . equal ( 1 ) ;
118+ chai . expect ( bulkDocsStub . args [ 0 ] [ 0 ] ) . to . deep . equal ( {
119+ docs : [
120+ { _id : 'purged:r2' , _rev : '2-rev' } ,
121+ { _id : 'purged:r3' } ,
122+ ]
123+ } ) ;
124+ chai . expect ( results ) . to . deep . equal ( [ { id : 'purged:r2' , rev : '3-rev' } ] ) ;
125+ } ) ;
126+
127+ it ( 'should throw on conflicts' , async ( ) => {
128+ const bulkDocsStub = sinon . stub ( ) . resolves ( [
129+ { id : 'purged:r2' , rev : '3-rev' } ,
130+ { id : 'purged:r3' , error : 'conflict' } ,
131+ { id : 'purged:r4' , error : 'conflict' } ,
132+ ] ) ;
133+ const fakeDb = { bulkDocs : ( args ) => bulkDocsStub ( args ) } ;
134+
135+ try {
136+ await service . __get__ ( 'bulkDocs' ) ( fakeDb , [ { _id : 'purged:r2' } , { _id : 'purged:r3' } , { _id : 'purged:r4' } ] ) ;
137+ throw new Error ( 'expected error' ) ;
138+ } catch ( e ) {
139+ chai . expect ( e . message ) . to . contain ( 'Conflicts while purging' ) ;
140+ chai . expect ( e . message ) . to . contain ( 'purged:r3' ) ;
141+ chai . expect ( e . message ) . to . contain ( 'purged:r4' ) ;
142+ }
143+ } ) ;
144+ } ) ;
145+
146+ describe ( 'assignRecordsToGroups' , ( ) => {
147+ it ( 'should assign records by subject to existing group and standalone for missing subject' , ( ) => {
148+ const groups = {
149+ c1 : { contact : { _id : 'c1' } , reports : [ ] , messages : [ ] , ids : [ ] , subjectIds : [ 'subj-1' ] } ,
150+ } ;
151+
152+ const hits = [
153+ // report with subject maps to c1
154+ { fields : { subject : 'subj-1' } , doc : { _id : 'r1' , form : 'X' } } ,
155+ // message with key not matching any group -> ignored until assignment
156+ { fields : { key : 'phone:+1' } , doc : { _id : 'm1' } } ,
157+ // report with missing subject -> standalone
158+ { fields : { } , doc : { _id : 'r2' , form : 'Y' } } ,
159+ ] ;
160+
161+ service . __get__ ( 'assignRecordsToGroups' ) ( hits , groups ) ;
162+
163+ chai . expect ( groups . c1 . reports . map ( r => r . _id ) ) . to . deep . equal ( [ 'r1' ] ) ;
164+ chai . expect ( groups . c1 . messages ) . to . deep . equal ( [ ] ) ; // message key didn’t match any subjectIds
165+ chai . expect ( groups [ 'r2' ] ) . to . deep . include ( { reports : [ { _id : 'r2' , form : 'Y' } ] } ) ;
166+ chai . expect ( groups [ 'r2' ] . messages ) . to . deep . equal ( [ ] ) ;
167+ } ) ;
168+ } ) ;
169+
170+ describe ( 'getRecordsForContactsBatch' , ( ) => {
171+ it ( 'should return empty for empty input' , async ( ) => {
172+ const res = await service . __get__ ( 'getRecordsForContactsBatch' ) ( [ ] ) ;
173+ chai . expect ( res ) . to . deep . equal ( [ ] ) ;
174+ } ) ;
175+ } ) ;
176+
77177 describe ( 'getRoles' , ( ) => {
78178 beforeEach ( ( ) => {
79179 sinon . stub ( db . users , 'allDocs' ) ;
0 commit comments