@workast/sdk 3.0.0 → 3.2.0

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/README.md CHANGED
@@ -89,6 +89,75 @@ try {
89
89
 
90
90
  Methods use `create` / `retrieve` / `update` / `list` / `del`, plus domain verbs like `complete` and `assign`. Path ids first, body second, request options last. Types match the [API reference](https://developers.workast.com/).
91
91
 
92
+ ## Testing
93
+
94
+ `@workast/sdk/mock` stubs SDK methods on any `Workast` instance (including one your app already constructed). No real HTTP while a mock is active. It also exports `examples`: Public API response fixtures (`examples.task`, `examples.list`, `examples.userResource`, …) generated from the spec. Spread them in `.resolves()` and override the fields your test cares about.
95
+
96
+ ```ts
97
+ import { Workast } from '@workast/sdk';
98
+ import { examples, mockWorkast } from '@workast/sdk/mock';
99
+
100
+ const workast = new Workast({ apiKey: process.env.WORKAST_API_KEY });
101
+
102
+ async function createShipTask() {
103
+ return workast.tasks.create(examples.list.id, { text: examples.task.text });
104
+ }
105
+
106
+ const mock = mockWorkast();
107
+ mock.tasks.create.on(examples.list.id, { text: examples.task.text }).resolves({
108
+ ...examples.task,
109
+ text: 'Ship from my test',
110
+ });
111
+
112
+ const created = await createShipTask();
113
+
114
+ expect(created.text).toBe('Ship from my test');
115
+ expect(mock.calls()).toEqual([
116
+ { method: 'tasks.create', args: [examples.list.id, { text: examples.task.text }] },
117
+ ]);
118
+ ```
119
+
120
+ ```ts
121
+ mock.users.me.on().resolves({ ...examples.userResource, name: 'Ada Lovelace' });
122
+ ```
123
+
124
+ `.on(...args)` is a prefix: extra trailing options on the real call still match. Nested objects match regardless of key order. Pass a function for a loose match (`true` → match):
125
+
126
+ ```ts
127
+ mock.tasks.create.on(examples.list.id, (body) => body.text === examples.task.text).resolves({
128
+ ...examples.task,
129
+ });
130
+ ```
131
+
132
+ Queue errors with `.rejects()`. `errors.*` are the same classes the client throws:
133
+
134
+ ```ts
135
+ import { AuthenticationError } from '@workast/sdk';
136
+ import { errors } from '@workast/sdk/mock';
137
+
138
+ mock.users.me.on().rejects(errors.unauthorized);
139
+ await expect(workast.users.me()).rejects.toBeInstanceOf(AuthenticationError);
140
+ ```
141
+
142
+ | Helper | Meaning |
143
+ | --- | --- |
144
+ | `mock.calls()` | Every SDK call while this mock is active (`{ method, args }`). |
145
+ | `mock.pending()` | Interceptors that were not used. |
146
+ | `interceptor.wasCalled()` | Whether that `.resolves()` / `.rejects()` fired. |
147
+ | `mock.reset()` | Clear queue and calls. Stay intercepting. |
148
+ | `mock.restore()` | Unpatch. Later SDK calls hit the real API. |
149
+
150
+ One mock per test, or one shared mock and `reset()` between tests:
151
+
152
+ ```ts
153
+ const mock = mockWorkast();
154
+
155
+ afterEach(() => mock.reset());
156
+ afterAll(() => mock.restore());
157
+ ```
158
+
159
+ `mockWorkast()` last-wins: a second call replaces the active queue. Unmatched SDK methods throw and list pending interceptors.
160
+
92
161
  ## Upgrading from v2
93
162
 
94
163
  v3 is a rewrite. The v2 positional constructor, `apiCall`, and generated resource helpers are gone. A string argument is now a secret `apiKey` (server-only), not a session token.