@raidiant/notifai 0.1.7 → 0.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.
@@ -141,9 +141,61 @@ describe('draft building', () => {
141
141
  presentation: { title: 'T', body: 'B' },
142
142
  targets: { mode: 'all' },
143
143
  delivery: { ttl_seconds: 86400, collapse_key: null },
144
+ platform: {
145
+ ios: { sound: null, interruption_level: 'passive' },
146
+ macos: { sound: null, interruption_level: 'passive' },
147
+ },
144
148
  })
145
149
  })
146
150
 
151
+ it.each([
152
+ { flags: {}, sound: null, level: 'passive' },
153
+ { flags: { kind: 'done' }, sound: 'done', level: 'passive' },
154
+ { flags: { reply: true }, sound: 'attention', level: 'active' },
155
+ ])('derives the $sound / $level kind profile from $flags', ({ flags, sound, level }) => {
156
+ const config = loadConfig({ cwd: base.cwd, env: base.env })
157
+ const build = buildDraft(config, { title: 'T', body: 'B', ...flags })
158
+ if (!build.ok) throw new Error(build.error)
159
+ expect(build.draft.platform).toEqual({
160
+ ios: { sound, interruption_level: level },
161
+ macos: { sound, interruption_level: level },
162
+ })
163
+ })
164
+
165
+ it('orders explicit flags over user config over the kind profile', () => {
166
+ const { env, cwd } = setup({
167
+ projectToml: 'sound = "alert"\ninterruption_level = "active"\n',
168
+ })
169
+ const config = loadConfig({ cwd, env })
170
+ const configured = buildDraft(config, { title: 'T', body: 'B', kind: 'done' })
171
+ if (!configured.ok) throw new Error(configured.error)
172
+ expect(configured.draft.platform?.ios).toEqual({
173
+ sound: 'alert',
174
+ interruption_level: 'active',
175
+ })
176
+
177
+ const explicit = buildDraft(config, {
178
+ title: 'T',
179
+ body: 'B',
180
+ kind: 'done',
181
+ sound: 'none',
182
+ level: 'time_sensitive',
183
+ })
184
+ if (!explicit.ok) throw new Error(explicit.error)
185
+ expect(explicit.draft.platform?.ios).toEqual({
186
+ sound: null,
187
+ interruption_level: 'time_sensitive',
188
+ })
189
+ })
190
+
191
+ it('keeps a blocking reply answerable for one hour by default', () => {
192
+ const config = loadConfig({ cwd: base.cwd, env: base.env })
193
+ const build = buildDraft(config, { title: 'Question', body: 'Deploy?', reply: true })
194
+ if (!build.ok) throw new Error(build.error)
195
+
196
+ expect(build.draft.reply?.expires_in_seconds).toBe(3_600)
197
+ })
198
+
147
199
  it('stamps the project from flag or project config', () => {
148
200
  const { env, cwd } = setup({ projectToml: 'project = "my-app"\n' })
149
201
  const config = loadConfig({ cwd, env })
@@ -200,6 +252,7 @@ describe('draft building', () => {
200
252
  interruption_level: 'time_sensitive',
201
253
  custom_data: { run_id: '42', branch: 'main' },
202
254
  })
255
+ expect(build.draft.platform?.macos).toEqual(build.draft.platform?.ios)
203
256
  })
204
257
 
205
258
  it('maps optional fields into the selected macOS platform slot', () => {
@@ -209,11 +262,8 @@ describe('draft building', () => {
209
262
  body: 'B',
210
263
  platform: 'macos',
211
264
  sound: 'none',
212
- badge: 7,
213
265
  threadId: 'desktop-builds',
214
266
  level: 'passive',
215
- relevance: 0.8,
216
- targetContentId: 'build-detail',
217
267
  data: ['run_id=42'],
218
268
  })
219
269
  if (!build.ok) throw new Error(build.error)
@@ -222,16 +272,28 @@ describe('draft building', () => {
222
272
  expect(build.draft.platform).toEqual({
223
273
  macos: {
224
274
  sound: null,
225
- badge: 7,
226
275
  thread_id: 'desktop-builds',
227
276
  interruption_level: 'passive',
228
- relevance_score: 0.8,
229
- target_content_id: 'build-detail',
230
277
  custom_data: { run_id: '42' },
231
278
  },
232
279
  })
233
280
  })
234
281
 
282
+ it('limits collapse keys by UTF-8 bytes', () => {
283
+ const config = loadConfig({ cwd: base.cwd, env: base.env })
284
+ expect(buildDraft(config, { title: 'T', body: 'B', collapseKey: '😀'.repeat(16) }).ok).toBe(
285
+ true,
286
+ )
287
+ const oversized = buildDraft(config, {
288
+ title: 'T',
289
+ body: 'B',
290
+ collapseKey: '😀'.repeat(17),
291
+ })
292
+ expect(oversized.ok).toBe(false)
293
+ if (oversized.ok) throw new Error('expected rejection')
294
+ expect(oversized.error).toContain('64 UTF-8 bytes')
295
+ })
296
+
235
297
  it('rejects malformed inputs with usage errors', () => {
236
298
  const config = loadConfig({ cwd: base.cwd, env: base.env })
237
299
  expect(buildDraft(config, { title: '', body: 'B' }).ok).toBe(false)