@sprucelabs/spruce-cli
Version:
Command line interface for building Spruce skills.
270 lines • 13.1 kB
JavaScript
;
var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
return c > 3 && r && Object.defineProperty(target, key, r), r;
};
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
const mercury_types_1 = require("@sprucelabs/mercury-types");
const spruce_event_utils_1 = require("@sprucelabs/spruce-event-utils");
const spruce_skill_utils_1 = require("@sprucelabs/spruce-skill-utils");
const test_utils_1 = require("@sprucelabs/test-utils");
const test_utils_2 = require("@sprucelabs/test-utils");
const EventStore_1 = __importDefault(require("../../features/event/stores/EventStore"));
const AbstractEventTest_1 = __importDefault(require("../../tests/AbstractEventTest"));
const constants_1 = require("../../tests/constants");
const test_utility_1 = __importDefault(require("../../tests/utilities/test.utility"));
const EVENT_NAME_READABLE = 'my event store amazing event';
const EVENT_NAME = 'my-event-store-amazing-event';
const EVENT_CAMEL = 'myEventStoreAmazingEvent';
class EventStoreTest extends AbstractEventTest_1.default {
static createAction;
static events;
static get version() {
return spruce_skill_utils_1.versionUtil.generateVersion();
}
static async beforeEach() {
await super.beforeEach();
this.createAction = this.Action('event', 'create');
spruce_skill_utils_1.diskUtil.writeFile(this.resolvePath('package.json'), '{}');
await this.people.loginAsDemoPerson(constants_1.DEMO_NUMBER_EVENT_STORE);
this.events = this.Store('event');
}
static async hasFetchEventContractsMethod() {
test_utils_1.assert.isFunction(this.events.fetchEventContracts);
}
static async fetchesCoreEventContracts() {
const results = await this.events.fetchEventContracts({
localNamespace: 'my-skill',
});
const { contracts, errors } = results;
test_utils_1.assert.isTrue(contracts.length >= 1);
for (const contract of contracts) {
(0, mercury_types_1.validateEventContract)(contract);
}
test_utils_1.assert.isEqual(errors.length, 0);
}
static async registerEventContract() {
const organizationFixture = this.getOrganizationFixture();
const org = await organizationFixture.seedDemoOrg({
name: 'my new org',
});
const { eventStore: eventStore1, skill: skill1 } = await this.seedSkillAndInstallAtOrg(org, 'skill 1');
const { eventStore: eventStore2 } = await this.seedSkillAndInstallAtOrg(org, 'skill 2');
await eventStore1.registerEventContract({
eventContract: {
eventSignatures: {
[`my-fantastic-event::${this.version.constValue}`]: {
emitPayloadSchema: (0, spruce_event_utils_1.buildEmitTargetAndPayloadSchema)({
eventName: `my-fantastic-event::${this.version.constValue}`,
targetSchema: spruce_event_utils_1.eventTargetSchema,
}),
emitPermissionContract: (0, mercury_types_1.buildPermissionContract)({
id: 'my-fantastic-event-contract',
name: 'Fantastic emit perms',
permissions: [
{
id: 'can-emit-perms',
name: 'can emit perm',
defaults: {
skill: false,
},
},
],
}),
},
},
},
});
const { contracts } = await eventStore2.fetchEventContracts({
localNamespace: 'my-skill',
});
test_utils_1.assert.isTrue(contracts.length > 2);
const skillContract = contracts[1];
const sig = spruce_event_utils_1.eventContractUtil.getSignatureByName(skillContract, `${skill1.slug}.my-fantastic-event::${this.version.constValue}`);
test_utils_1.assert.isEqual(sig.emitPermissionContract?.id, `${skill1.slug}.my-fantastic-event-contract`);
}
static async badLocalContractThrowsNiceError() {
await this.FeatureFixture().installCachedFeatures('events');
const skill = await this.getSkillFixture().registerCurrentSkill({
name: 'my new skill',
});
const results = await this.createAction.execute({
nameReadable: EVENT_NAME_READABLE,
nameKebab: EVENT_NAME,
nameCamel: EVENT_CAMEL,
});
test_utils_1.assert.isFalsy(results.errors);
const match = test_utility_1.default.assertFileByNameInGeneratedFiles(`emitPayload.builder.ts`, results.files);
spruce_skill_utils_1.diskUtil.writeFile(match, 'export default {}');
const err = await test_utils_1.assert.doesThrowAsync(() => this.events.loadLocalContract(skill.slug), new RegExp(`${skill.slug}.${EVENT_NAME}::${spruce_skill_utils_1.versionUtil.generateVersion().constValue}`));
test_utils_2.errorAssert.assertError(err, 'INVALID_EVENT_CONTRACT');
}
static async badLocalSignature() {
await this.installEventsSkill();
const skill = await this.getSkillFixture().registerCurrentSkill({
name: 'my new skill',
});
const results = await this.createAction.execute({
nameReadable: EVENT_NAME_READABLE,
nameKebab: EVENT_NAME,
nameCamel: EVENT_CAMEL,
});
test_utils_1.assert.isFalsy(results.errors);
const match = test_utility_1.default.assertFileByNameInGeneratedFiles(`event.options.ts`, results.files);
spruce_skill_utils_1.diskUtil.writeFile(match, 'export default {waka: true}');
const err = await test_utils_1.assert.doesThrowAsync(() => this.events.loadLocalContract(skill.slug), new RegExp(`${skill.slug}.${EVENT_NAME}::${spruce_skill_utils_1.versionUtil.generateVersion().constValue}`));
test_utils_2.errorAssert.assertError(err, 'INVALID_EVENT_CONTRACT');
}
static async mixesInLocalContracts() {
await this.installEventsSkill();
const skill = await this.getSkillFixture().registerCurrentSkill({
name: 'my new skill',
});
await this.createAction.execute({
nameReadable: EVENT_NAME_READABLE,
nameKebab: EVENT_NAME,
nameCamel: EVENT_CAMEL,
});
await this.copyEventBuildersAndPermissions(EVENT_NAME);
await this.Action('event', 'sync').execute({});
const { contracts } = await this.events.fetchEventContracts({
localNamespace: skill.slug,
namespaces: ['core'],
});
test_utils_1.assert.isLength(contracts, 2);
const name = spruce_event_utils_1.eventNameUtil.join({
eventName: EVENT_NAME,
eventNamespace: skill.slug,
version: this.version.constValue,
});
let wasFound = false;
for (const contract of contracts) {
if (contract.eventSignatures[name]?.emitPayloadSchema) {
wasFound = true;
test_utils_1.assert.isEqual(contract.eventSignatures[name].emitPayloadSchema?.id, EVENT_CAMEL + 'EmitTargetAndPayload');
test_utils_1.assert.isTruthy(contract.eventSignatures[name].emitPayloadSchema?.fields
?.target);
test_utils_1.assert.isTruthy(contract.eventSignatures[name].emitPayloadSchema?.fields
?.payload);
test_utils_1.assert.isTruthy(contract.eventSignatures[name].responsePayloadSchema);
test_utils_1.assert.isTruthy(contract.eventSignatures[name].emitPermissionContract);
test_utils_1.assert.isTruthy(contract.eventSignatures[name].listenPermissionContract);
(0, mercury_types_1.validateEventContract)(contract);
}
}
test_utils_1.assert.isTrue(wasFound);
}
static async mixesInLocalContractWithGlobalEventsAndDoesNotReturnContractTwice() {
const { skill, fqen } = await this.installAndRegisterOneGlobalEvent();
const { contracts } = await this.events.fetchEventContracts({
localNamespace: skill.slug,
});
const totalMatches = contracts.reduce((count, contract) => {
if (contract.eventSignatures[fqen]) {
count++;
}
return count;
}, 0);
test_utils_1.assert.isEqual(totalMatches, 1);
}
static async doesNotLoadGlobalContractsForSelf() {
const { fqen, skill } = await this.installAndRegisterOneGlobalEvent();
const eventsPath = this.resolvePath('src', 'events');
spruce_skill_utils_1.diskUtil.deleteDir(eventsPath);
const { contracts } = await this.events.fetchEventContracts({
localNamespace: skill.slug,
});
const unified = spruce_event_utils_1.eventContractUtil.unifyContracts(contracts);
test_utils_1.assert.isTruthy(unified);
test_utils_1.assert.doesThrow(() => spruce_event_utils_1.eventContractUtil.getSignatureByName(unified, fqen));
}
static async globbyPatternLooksEverywhere() {
const store = this.events;
const expected = this.resolvePath('src', '**', 'events', '**/*.(builder|options).ts');
//@ts-ignore
test_utils_1.assert.isEqual(store.generateGlobbyForLocalEvents(), expected);
}
static async passesBackJsErrorsWhenFetchingEventContracts() {
const msg = (0, test_utils_1.generateId)();
this.events = this.Store('event', {
apiClientFactory: async () => {
throw new Error(msg);
},
});
await test_utils_1.assert.doesThrowAsync(() => this.events.fetchEventContracts(), msg);
}
static async installAndRegisterOneGlobalEvent() {
await this.installEventsSkill();
const skill = await this.getSkillFixture().registerCurrentSkill({
name: 'event store test skill',
});
const results = await this.createAction.execute({
nameReadable: EVENT_NAME_READABLE,
nameKebab: EVENT_NAME,
nameCamel: EVENT_CAMEL,
isGlobal: true,
});
const { fqen } = results.meta ?? {};
test_utils_1.assert.isTruthy(fqen);
const boot = await this.Action('skill', 'boot').execute({ local: true });
boot.meta?.kill();
EventStore_1.default.clearCache();
return { boot, skill, fqen, createResults: results };
}
static async seedSkillAndInstallAtOrg(org, name) {
const skill = await this.getSkillFixture().seedDemoSkill({
name,
});
await this.getOrganizationFixture().installSkillAtOrganization(skill.id, org.id);
const client = await this.connectToApi({
skillId: skill.id,
apiKey: skill.apiKey,
});
const eventStore = this.Store('event', {
apiClientFactory: async () => {
return client;
},
});
return { eventStore, skill };
}
static async installEventsSkill() {
await this.FeatureFixture().installCachedFeatures('events');
}
}
exports.default = EventStoreTest;
__decorate([
(0, test_utils_1.test)()
], EventStoreTest, "hasFetchEventContractsMethod", null);
__decorate([
(0, test_utils_1.test)()
], EventStoreTest, "fetchesCoreEventContracts", null);
__decorate([
(0, test_utils_1.test)()
], EventStoreTest, "registerEventContract", null);
__decorate([
(0, test_utils_1.test)()
], EventStoreTest, "badLocalContractThrowsNiceError", null);
__decorate([
(0, test_utils_1.test)()
], EventStoreTest, "badLocalSignature", null);
__decorate([
(0, test_utils_1.test)()
], EventStoreTest, "mixesInLocalContracts", null);
__decorate([
(0, test_utils_1.test)()
], EventStoreTest, "mixesInLocalContractWithGlobalEventsAndDoesNotReturnContractTwice", null);
__decorate([
(0, test_utils_1.test)()
], EventStoreTest, "doesNotLoadGlobalContractsForSelf", null);
__decorate([
(0, test_utils_1.test)()
], EventStoreTest, "globbyPatternLooksEverywhere", null);
__decorate([
(0, test_utils_1.test)()
], EventStoreTest, "passesBackJsErrorsWhenFetchingEventContracts", null);
//# sourceMappingURL=EventStore.test.js.map