Ctrl K
ComunidadGuías…

test/linear-launch.test.js

Rama main · réplica de lectura del repositorio original.

Archivo original ↗Preguntar a KiBot
var test = require('node:test');
var assert = require('node:assert/strict');
var start = require('../lib/project-linear-launch').attachLinearLaunch;
function world() {
  var calls = 0, created = 0, saved = 0, sessions = new Map(), events = [];
  var ws = { readyState: 1, _clayUser: { id: 'owner' } };
  var ctx = { osUsers: true, getLinuxUserForSession: function () { return 'owner-os'; }, ensureProjectAccessForSession: function () { return 'owner-os'; },
    getProjectAccess: function () { return { visibility: 'public' }; }, resolveDefaultAi: async function () { return { ready: true, vendor: 'claude', model: 'model' }; }, onProcessingChanged: function () {},
    sm: { sessions: sessions, installedVendors: ['claude'], createSessionRaw: function (options) { var session = Object.assign({ localId: ++created, history: [] }, options); sessions.set(session.localId, session); return session; },
      saveSessionFile: function () { saved++; return true; }, deleteSession: function (id) { sessions.delete(id); }, switchSession: function () {}, sendAndRecord: function (session, event) { events.push(event); }, sendToSession: function () {}, broadcastSessionList: function () {} },
    getSdk: function () { return { startQuery: async function (session, prompt) { calls++; assert.match(prompt, /Do not commit/); assert.match(prompt, /Requirements/); session.queryInstance = {}; } }; } };
  var issue = { id: 'id', identifier: 'ENG-123', url: 'https://linear.app/acme/issue/ENG-123', title: 'Fix', description: 'Requirements', comments: [], pageInfo: { hasNextPage: false } };
  return { ctx: ctx, issue: issue, ws: ws, launch: start(ctx), sessions: sessions, calls: function () { return calls; }, created: function () { return created; }, events: events };
}
test('starting Linear work coalesces requests, preserves context and reopens the existing session', async function () {
  var w = world();
  var results = await Promise.all([w.launch(w.ws, w.issue, function () {}), w.launch(w.ws, w.issue, function () {})]);
  assert.equal(w.calls(), 1); assert.equal(w.created(), 1); assert.equal(results[0].sessionId, results[1].sessionId);
  var session = w.sessions.get(1); assert.equal(session.linearLinks[0].description, undefined); assert.equal(session.ownerId, 'owner');
  assert.equal(session.sessionVisibility, 'private');
  var existing = await w.launch(w.ws, w.issue, function () {}); assert.equal(existing.existing, true); assert.equal(w.calls(), 1);
});
test('revoked access after runtime selection prevents session creation', async function () {
  var w = world(), allowed = true;
  w.ctx.resolveDefaultAi = async function () { allowed = false; return { ready: true, vendor: 'claude' }; };
  await assert.rejects(w.launch(w.ws, w.issue, function () { if (!allowed) throw new Error('revoked'); }), /revoked/);
  assert.equal(w.created(), 0);
});
test('OS identity changes and persistence failures do not dispatch', async function () {
  var w = world(); w.ctx.ensureProjectAccessForSession = function () { return 'other'; };
  await assert.rejects(w.launch(w.ws, w.issue, function () {}), /identity/); assert.equal(w.calls(), 0); assert.equal(w.sessions.size, 0);
  w = world(); w.ctx.sm.saveSessionFile = function () { return false; };
  await assert.rejects(w.launch(w.ws, w.issue, function () {}), /save/); assert.equal(w.calls(), 0); assert.equal(w.sessions.size, 0);
});
test('runtime failure retains the linked conversation with an actionable error', async function () {
  var w = world(); w.ctx.getSdk = function () { return { startQuery: async function () { throw new Error('runtime unavailable'); } }; };
  await assert.rejects(w.launch(w.ws, w.issue, function () {}), function (error) { return error.sessionId === 1; });
  assert.equal(w.sessions.get(1).isProcessing, false); assert.equal(w.events.at(-1).type, 'error');
});