toBe(0); expect($result)->toHaveKey('generated'); }); it('returns zero total for a CSV with only pending signatures', function () { $path = mapTestCsv([ PETITION_MAP_CSV_HEADER, [time(), 'a@b.com', 'Ola', 'Hansen', 'oslo', 'semi', 'pending', 'tok1', time(), 'hash1'], ]); expect(petitionMapBuildData($path)['total'])->toBe(0); unlink($path); }); it('returns zero total for a CSV with only the header', function () { $path = mapTestCsv([PETITION_MAP_CSV_HEADER]); expect(petitionMapBuildData($path)['total'])->toBe(0); unlink($path); }); // --- petitionMapBuildData: counting confirmed signatures --- it('counts confirmed signatures and groups them by region', function () { $path = mapTestCsv([ PETITION_MAP_CSV_HEADER, [time(), 'a@b.com', 'Kari', 'Hansen', 'oslo', 'semi', 'confirmed', 't1', time(), 'h1'], [time(), 'b@b.com', 'Ola', 'Nilsen', 'oslo', 'semi', 'confirmed', 't2', time(), 'h2'], [time(), 'c@b.com', 'Per', 'Olsen', 'bergen', 'semi', 'confirmed', 't3', time(), 'h3'], ]); $result = petitionMapBuildData($path); expect($result['total'])->toBe(3); expect($result['regions']['oslo']['count'])->toBe(2); expect($result['regions']['bergen']['count'])->toBe(1); unlink($path); }); it('ignores non-confirmed rows (pending, deleted, etc.)', function () { $path = mapTestCsv([ PETITION_MAP_CSV_HEADER, [time(), 'a@b.com', 'Kari', 'Hansen', 'oslo', 'semi', 'confirmed', 't1', time(), 'h1'], [time(), 'b@b.com', 'Ola', 'Nilsen', 'oslo', 'semi', 'pending', 't2', time(), 'h2'], [time(), 'c@b.com', 'Per', 'Olsen', 'oslo', 'semi', 'deleted', 't3', time(), 'h3'], ]); $result = petitionMapBuildData($path); expect($result['total'])->toBe(1); unlink($path); }); it('skips confirmed entries that have no region', function () { $path = mapTestCsv([ PETITION_MAP_CSV_HEADER, [time(), 'a@b.com', 'Kari', 'Hansen', '', 'semi', 'confirmed', 't1', time(), 'h1'], ]); expect(petitionMapBuildData($path)['total'])->toBe(0); unlink($path); }); // --- petitionMapBuildData: name handling --- it('uses only the first word of the firstname', function () { $path = mapTestCsv([ PETITION_MAP_CSV_HEADER, [time(), 'a@b.com', 'Kari Marte', 'Hansen', 'oslo', 'semi', 'confirmed', 't1', time(), 'h1'], ]); $signer = petitionMapBuildData($path)['regions']['oslo']['signers'][0]; expect($signer['n'])->toBe('Kari'); unlink($path); }); it('sets name to null and anonymous flag true for anonymous display', function () { $path = mapTestCsv([ PETITION_MAP_CSV_HEADER, [time(), 'a@b.com', 'Kari', 'Hansen', 'oslo', 'anonymous', 'confirmed', 't1', time(), 'h1'], ]); $signer = petitionMapBuildData($path)['regions']['oslo']['signers'][0]; expect($signer['n'])->toBeNull(); expect($signer['a'])->toBeTrue(); unlink($path); }); it('sets anonymous flag false for non-anonymous display', function () { $path = mapTestCsv([ PETITION_MAP_CSV_HEADER, [time(), 'a@b.com', 'Lars', 'Berg', 'oslo', 'semi', 'confirmed', 't1', time(), 'h1'], ]); $signer = petitionMapBuildData($path)['regions']['oslo']['signers'][0]; expect($signer['a'])->toBeFalse(); unlink($path); }); it('does not include emails, surnames, tokens, or ip_hashes in the output', function () { $path = mapTestCsv([ PETITION_MAP_CSV_HEADER, [time(), 'secret@b.com', 'Lars', 'SecretSurname', 'oslo', 'semi', 'confirmed', 'secret-token', time(), 'secret-hash'], ]); $result = petitionMapBuildData($path); $json = json_encode($result); expect($json)->not->toContain('secret@b.com'); expect($json)->not->toContain('SecretSurname'); expect($json)->not->toContain('secret-token'); expect($json)->not->toContain('secret-hash'); unlink($path); });