Classify a deliver_sm by esm_class and document the messageDlr precondition
This commit is contained in:
+41
-4
@@ -1,17 +1,22 @@
|
||||
import assert from 'node:assert/strict';
|
||||
import test, { describe } from 'node:test';
|
||||
import { consts } from '../src/defs/constants.ts';
|
||||
import { dlrFromPdu, parseReceipt, receiptCodes } from '../src/dlr.ts';
|
||||
import { objToPdu, pduToObj } from '../src/pdu.ts';
|
||||
import type { PduObject, TlvInput } from '../src/pdu.ts';
|
||||
|
||||
const receiptText = 'id:0195f0c7 sub:001 dlvrd:001 submit date:2508251430 done date:2508251431 stat:DELIVRD err:000 text:hello';
|
||||
|
||||
function deliverSm(message: string, tlvs?: Record<string, TlvInput>): PduObject {
|
||||
function deliverSm(
|
||||
message: string,
|
||||
tlvs?: Record<string, TlvInput>,
|
||||
esmClass: number = consts.ESM_CLASS.MC_DELIVERY_RECEIPT,
|
||||
): PduObject {
|
||||
const { buffer } = objToPdu({
|
||||
cmdName: 'deliver_sm',
|
||||
params: {
|
||||
destination_addr: '46701113311',
|
||||
esm_class: 4,
|
||||
esm_class: esmClass,
|
||||
short_message: message,
|
||||
source_addr: '46709771337',
|
||||
},
|
||||
@@ -112,8 +117,40 @@ describe('dlrFromPdu()', () => {
|
||||
assert.equal(dlrFromPdu(deliverSm('id:x stat:DELIVRD done date:2501012560'))?.doneDate, undefined);
|
||||
});
|
||||
|
||||
test('returns nothing when the PDU identifies no message', () => {
|
||||
assert.equal(dlrFromPdu(deliverSm('just a normal sms')), undefined);
|
||||
test('returns nothing when an unmarked deliver_sm identifies no message', () => {
|
||||
assert.equal(dlrFromPdu(deliverSm('just a normal sms', undefined, 0)), undefined);
|
||||
});
|
||||
|
||||
test('still reads the body when the peer marks no message type', () => {
|
||||
const dlr = dlrFromPdu(deliverSm(receiptText, undefined, 0));
|
||||
|
||||
assert.ok(dlr);
|
||||
assert.equal(dlr.smsId, '0195f0c7');
|
||||
assert.equal(dlr.statusMsg, 'DELIVERED');
|
||||
});
|
||||
|
||||
test('reports a marked receipt whose body it cannot read, rather than an inbound message', () => {
|
||||
const dlr = dlrFromPdu(deliverSm('a receipt in a format nobody documented'));
|
||||
|
||||
assert.ok(dlr);
|
||||
assert.equal(dlr.smsId, undefined);
|
||||
assert.equal(dlr.statusMsg, 'UNKNOWN');
|
||||
assert.equal(dlr.statusId, 7);
|
||||
|
||||
const withUdh = consts.ESM_CLASS.MC_DELIVERY_RECEIPT | consts.ESM_CLASS.UDH_INDICATOR;
|
||||
|
||||
assert.ok(dlrFromPdu(deliverSm(receiptText, undefined, withUdh)));
|
||||
});
|
||||
|
||||
test('leaves a message the peer marked as another type to arrive as an SMS', () => {
|
||||
for (const esmClass of [
|
||||
consts.ESM_CLASS.CONVERSATION_ABORT,
|
||||
consts.ESM_CLASS.DELIVERY_ACKNOWLEDGEMENT,
|
||||
consts.ESM_CLASS.INTERMEDIATE_DELIVERY,
|
||||
consts.ESM_CLASS.USER_ACKNOWLEDGEMENT,
|
||||
]) {
|
||||
assert.equal(dlrFromPdu(deliverSm(receiptText, undefined, esmClass)), undefined);
|
||||
}
|
||||
});
|
||||
|
||||
test('exposes the raw receipt alongside the resolved fields', () => {
|
||||
|
||||
@@ -57,7 +57,7 @@ describe('merged delivery reports', () => {
|
||||
const merged = once<MessageDlr>(resolve => { session.on('messageDlr', resolve); });
|
||||
const perSegment: string[] = [];
|
||||
|
||||
session.on('dlr', dlr => perSegment.push(dlr.smsId));
|
||||
session.on('dlr', dlr => perSegment.push(dlr.smsId ?? ''));
|
||||
|
||||
const [sms] = await Promise.all([
|
||||
incoming.then(async received => {
|
||||
|
||||
+30
-2
@@ -711,6 +711,34 @@ describe('receiving', () => {
|
||||
assert.equal(answered.pduObj.params.message_id, 'inbound-id');
|
||||
});
|
||||
|
||||
test('hands a client a receipt it cannot read as a dlr rather than as an sms', async t => {
|
||||
const { peer, session } = await inbound(t);
|
||||
const reported = once<Dlr>(resolve => { session.on('dlr', resolve); });
|
||||
let messages = 0;
|
||||
|
||||
session.on('sms', () => { messages++; });
|
||||
|
||||
const delivered = peer.send({
|
||||
cmdName: 'deliver_sm',
|
||||
params: {
|
||||
destination_addr: '46709771337',
|
||||
esm_class: consts.ESM_CLASS.MC_DELIVERY_RECEIPT,
|
||||
short_message: 'a receipt in a format nobody documented',
|
||||
source_addr: '46701113311',
|
||||
},
|
||||
});
|
||||
const dlr = await raceWithin(2000, reported);
|
||||
|
||||
assert.ok(dlr, 'esm_class marks it a receipt, so nothing else may claim it');
|
||||
assert.equal(dlr.smsId, undefined);
|
||||
assert.equal(messages, 0);
|
||||
|
||||
const answered = await delivered;
|
||||
|
||||
assert.ok(answered.pduObj);
|
||||
assert.equal(answered.pduObj.cmdName, 'deliver_sm_resp');
|
||||
});
|
||||
|
||||
test('reassembles a multipart inbound SMS before the sms event', async t => {
|
||||
const message = 'Inbound lorem ipsum dolor sit amet consectetur, '.repeat(6);
|
||||
const { peer, session } = await inbound(t);
|
||||
@@ -757,7 +785,7 @@ describe('delivery reports', () => {
|
||||
|
||||
assert.ok(session);
|
||||
|
||||
const dlr = once<[{ smsId: string; statusMsg: string }, PduObject]>(resolve => {
|
||||
const dlr = once<[Dlr, PduObject]>(resolve => {
|
||||
session.on('dlr', (report, pduObj) => { resolve([report, pduObj]); });
|
||||
});
|
||||
|
||||
@@ -873,7 +901,7 @@ describe('delivery reports', () => {
|
||||
const perSegment: string[] = [];
|
||||
let merged = 0;
|
||||
|
||||
session.on('dlr', dlr => perSegment.push(dlr.smsId));
|
||||
session.on('dlr', dlr => perSegment.push(dlr.smsId ?? ''));
|
||||
session.on('messageDlr', () => { merged++; });
|
||||
|
||||
const [sms] = await Promise.all([
|
||||
|
||||
Reference in New Issue
Block a user