vona-module-test-pay 5.0.1 → 5.0.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "vona-module-test-pay",
3
- "version": "5.0.1",
3
+ "version": "5.0.2",
4
4
  "description": "",
5
5
  "keywords": [
6
6
  "Vona Module"
@@ -30,8 +30,8 @@
30
30
  "postpack": "clean-package restore"
31
31
  },
32
32
  "dependencies": {
33
- "vona-module-a-pay": "5.0.2",
34
- "vona-module-pay-mock": "5.0.2"
33
+ "vona-module-a-pay": "5.0.3",
34
+ "vona-module-pay-mock": "5.0.3"
35
35
  },
36
36
  "title": "test-pay",
37
37
  "vonaModule": {
@@ -51,5 +51,5 @@
51
51
  }
52
52
  }
53
53
  },
54
- "gitHead": "95488ea0a7779f34f6ebddeca7719d8545bc55b3"
54
+ "gitHead": "e86b8ee51b837417b7b28b2c67862877d4092371"
55
55
  }
@@ -2,8 +2,8 @@ import type { IPaymentOutcomeEvent } from 'vona-module-a-pay';
2
2
 
3
3
  import assert from 'node:assert';
4
4
  import { randomUUID } from 'node:crypto';
5
- import { describe, it } from 'node:test';
6
- import { app } from 'vona-mock';
5
+ import { after, before, describe, it } from 'node:test';
6
+ import { acquireTestLock, app } from 'vona-mock';
7
7
 
8
8
  interface IFixture {
9
9
  userId?: number;
@@ -79,6 +79,16 @@ async function cleanup(fixture: IFixture) {
79
79
  }
80
80
 
81
81
  describe('outbox.test.ts', { concurrency: false }, () => {
82
+ let releaseTestLock: (() => void) | undefined;
83
+
84
+ before(async () => {
85
+ releaseTestLock = await acquireTestLock('a-pay');
86
+ });
87
+
88
+ after(() => {
89
+ releaseTestLock?.();
90
+ });
91
+
82
92
  it('claims, backs off, and exhausts durable delivery attempts', async () => {
83
93
  await app.bean.executor.mockCtx(async () => {
84
94
  const fixture = await createFixture(randomUUID().slice(0, 12));
@@ -100,7 +110,7 @@ describe('outbox.test.ts', { concurrency: false }, () => {
100
110
  assert.ok((persisted?.nextAttemptAt?.getTime() ?? 0) >= releaseStart + 900);
101
111
  assert.equal(await scope.service.outbox.claim(event.id), undefined);
102
112
  await scope.model.outboxEvent.updateById(event.id, {
103
- nextAttemptAt: new Date(Date.now() - 1),
113
+ nextAttemptAt: new Date(Date.now() - 1_000),
104
114
  });
105
115
  const second = await scope.service.outbox.claim(event.id);
106
116
  assert.equal(second?.attemptCount, 2);
@@ -150,7 +160,7 @@ describe('outbox.test.ts', { concurrency: false }, () => {
150
160
  const scope = app.scope('a-pay');
151
161
  const first = await scope.service.outbox.claim(event.id);
152
162
  await scope.model.outboxEvent.updateById(event.id, {
153
- claimExpiresAt: new Date(Date.now() - 1),
163
+ claimExpiresAt: new Date(Date.now() - 1_000),
154
164
  });
155
165
  const second = await scope.service.outbox.claim(event.id);
156
166
  assert.ok(second?.claimToken);
@@ -1,7 +1,7 @@
1
1
  import assert from 'node:assert';
2
2
  import { randomUUID } from 'node:crypto';
3
- import { describe, it } from 'node:test';
4
- import { app } from 'vona-mock';
3
+ import { after, before, describe, it } from 'node:test';
4
+ import { acquireTestLock, app } from 'vona-mock';
5
5
 
6
6
  interface IFixture {
7
7
  userId?: number;
@@ -38,7 +38,17 @@ async function cleanup(fixture: IFixture) {
38
38
  await app.bean.passport.signout();
39
39
  }
40
40
 
41
- describe('payMock.test.ts', { concurrency: false }, () => {
41
+ describe('payMock.test.ts', { concurrency: false, sequential: true }, () => {
42
+ let releaseTestLock: (() => void) | undefined;
43
+
44
+ before(async () => {
45
+ releaseTestLock = await acquireTestLock('a-pay');
46
+ });
47
+
48
+ after(() => {
49
+ releaseTestLock?.();
50
+ });
51
+
42
52
  it('captures Vona env secrets in the mock Provider options', () => {
43
53
  const options = app.bean.payProvider.getOptions('pay-mock:mock', 'default');
44
54
  assert.equal(options.secretCredential, app.meta.env.PAY_MOCK_DEFAULT_CREDENTIAL);
@@ -1,7 +1,7 @@
1
1
  import assert from 'node:assert';
2
2
  import { randomUUID } from 'node:crypto';
3
- import { describe, it } from 'node:test';
4
- import { app } from 'vona-mock';
3
+ import { after, before, describe, it } from 'node:test';
4
+ import { acquireTestLock, app } from 'vona-mock';
5
5
 
6
6
  interface IFixture {
7
7
  userId?: number;
@@ -27,6 +27,10 @@ async function createFixture(expiresAt: Date): Promise<IFixture> {
27
27
  async function cleanup(fixture: IFixture) {
28
28
  const scope = app.scope('a-pay');
29
29
  if (fixture.paymentSessionId !== undefined) {
30
+ await scope.model.outboxEvent.delete({ paymentSessionId: fixture.paymentSessionId });
31
+ await scope.model.webhookInbox.delete({ paymentSessionId: fixture.paymentSessionId });
32
+ await scope.model.providerOperation.delete({ paymentSessionId: fixture.paymentSessionId });
33
+ await scope.model.refundOperation.delete({ paymentSessionId: fixture.paymentSessionId });
30
34
  await scope.model.paymentAudit.delete({ paymentSessionId: fixture.paymentSessionId });
31
35
  await scope.model.paymentSession.delete({ id: fixture.paymentSessionId });
32
36
  }
@@ -37,6 +41,16 @@ async function cleanup(fixture: IFixture) {
37
41
  }
38
42
 
39
43
  describe('paymentSession.test.ts', { concurrency: false }, () => {
44
+ let releaseTestLock: (() => void) | undefined;
45
+
46
+ before(async () => {
47
+ releaseTestLock = await acquireTestLock('a-pay');
48
+ });
49
+
50
+ after(() => {
51
+ releaseTestLock?.();
52
+ });
53
+
40
54
  it('derives provider facts and expiry from the payment scene', async () => {
41
55
  await app.bean.executor.mockCtx(async () => {
42
56
  const scope = app.scope('a-pay');
@@ -102,9 +116,8 @@ describe('paymentSession.test.ts', { concurrency: false }, () => {
102
116
  const scope = app.scope('a-pay');
103
117
  const session = await scope.service.paymentSession.start(fixture.paymentSessionId!);
104
118
  assert.equal(session.state, 'requires_action');
105
- await assert.rejects(scope.service.paymentSession.start(fixture.paymentSessionId!), {
106
- status: 409,
107
- });
119
+ const replayed = await scope.service.paymentSession.start(fixture.paymentSessionId!);
120
+ assert.equal(replayed.state, 'requires_action');
108
121
  } finally {
109
122
  await cleanup(fixture);
110
123
  }
@@ -113,7 +126,7 @@ describe('paymentSession.test.ts', { concurrency: false }, () => {
113
126
 
114
127
  it('does not start an expired payment session', async () => {
115
128
  await app.bean.executor.mockCtx(async () => {
116
- const fixture = await createFixture(new Date(Date.now() - 1));
129
+ const fixture = await createFixture(new Date(Date.now() - 1_000));
117
130
  try {
118
131
  const scope = app.scope('a-pay');
119
132
  await assert.rejects(scope.service.paymentSession.start(fixture.paymentSessionId!), {
@@ -142,8 +155,13 @@ describe('paymentSession.test.ts', { concurrency: false }, () => {
142
155
  return await app.scope('a-pay').service.paymentSession.start(fixture.paymentSessionId!);
143
156
  }),
144
157
  ]);
145
- assert.equal(results.filter(result => result.status === 'fulfilled').length, 1);
146
- assert.equal(results.filter(result => result.status === 'rejected').length, 1);
158
+ assert.equal(results.filter(result => result.status === 'fulfilled').length, 2);
159
+ const operations = await app.bean.executor.mockCtx(async () => {
160
+ return await app.scope('a-pay').model.providerOperation.select({
161
+ where: { paymentSessionId: fixture.paymentSessionId, kind: 'start' },
162
+ });
163
+ });
164
+ assert.equal(operations.length, 1);
147
165
  } finally {
148
166
  await app.bean.executor.mockCtx(async () => {
149
167
  await cleanup(fixture);
@@ -1,7 +1,7 @@
1
1
  import assert from 'node:assert';
2
2
  import { createHmac, randomUUID } from 'node:crypto';
3
- import { describe, it } from 'node:test';
4
- import { app } from 'vona-mock';
3
+ import { after, before, describe, it } from 'node:test';
4
+ import { acquireTestLock, app } from 'vona-mock';
5
5
 
6
6
  interface IFixture {
7
7
  userId?: number;
@@ -100,6 +100,16 @@ async function countFacts(paymentSessionId: number) {
100
100
  }
101
101
 
102
102
  describe('webhook.test.ts', { concurrency: false, sequential: true }, () => {
103
+ let releaseTestLock: (() => void) | undefined;
104
+
105
+ before(async () => {
106
+ releaseTestLock = await acquireTestLock('a-pay');
107
+ });
108
+
109
+ after(() => {
110
+ releaseTestLock?.();
111
+ });
112
+
103
113
  it('accepts a raw-body signed HTTP webhook and rejects an invalid signature without mutation', async () => {
104
114
  const fixture: IFixture = {};
105
115
  try {