@sprucelabs/spruce-cli
Version:
Command line interface for building Spruce skills.
292 lines (253 loc) • 8.71 kB
text/typescript
import { MercuryClientFactory } from '@sprucelabs/mercury-client'
import { SpruceSchemas } from '@sprucelabs/mercury-types'
import { diskUtil } from '@sprucelabs/spruce-skill-utils'
import { test, assert, generateId } from '@sprucelabs/test-utils'
import PermissionStore, {
ImportedPermission,
ListPermContractsTargetAndPayload,
} from '../../../features/permission/stores/PermissionStore'
import { ApiClientFactoryOptions } from '../../../types/apiClient.types'
import AbstractPermissionsTest from './support/AbstractPermissionsTest'
import generateShortAlphaId from './support/generateShortAlphaId'
import { sortPermissionContracts } from './support/sortPermissionContracts'
export default class PermissionStoreTest extends AbstractPermissionsTest {
private static permissions: PermissionStore
private static contractName1: string
private static contractName2: string
private static fqid1: string
private static fqid2: string
private static namespace: string
protected static async beforeAll() {
await super.beforeAll()
const namespace = await this.Service('pkg').getSkillNamespace()
this.namespace = namespace
this.contractName1 = generateShortAlphaId()
this.fqid1 = `${namespace}.${this.contractName1}`
this.contractName2 = generateShortAlphaId()
const contractId = this.contractName2
this.fqid2 = buildPermissionContractId(contractId, namespace)
}
protected static async beforeEach() {
await super.beforeEach()
MercuryClientFactory.setIsTestMode(true)
this.permissions = this.Store('permission')
await this.eventFaker.fakeListPermissionContracts(() => {})
}
protected static async loadsNoLocalByDefault() {
const permissions = await this.loadLocalPermissions()
assert.isEqualDeep(permissions, [])
}
protected static async loadsOneContract() {
await this.createPermissionContract(this.contractName1)
await this.assertLocalPermissionsEqual([
{
id: this.fqid1,
permissions: ['can-high-five'],
path: this.resolvePath(
`src/permissions/${this.contractName1}.permissions.ts`
),
},
])
}
protected static async loadsSecondContract() {
await this.createPermissionContract(this.contractName2)
await this.assertLocalPermissionsEqual([
{
id: this.fqid2,
permissions: ['can-high-five'],
path: this.resolvePath(
`src/permissions/${this.contractName2}.permissions.ts`
),
},
{
id: this.fqid1,
permissions: ['can-high-five'],
path: this.resolvePath(
`src/permissions/${this.contractName1}.permissions.ts`
),
},
])
}
protected static async mixesInAllPermissions() {
const contractId = 'oeu-aoeuao'
const perm1Id = 'what-the'
const perm2Id = 'go-dogs'
this.updateFirstContractBuilder(contractId, perm1Id, perm2Id)
await this.assertLocalPermissionsEqual([
{
id: this.fqid2,
permissions: ['can-high-five'],
path: this.resolvePath(
`src/permissions/${this.contractName2}.permissions.ts`
),
},
{
id: buildPermissionContractId(contractId, this.namespace),
permissions: [perm1Id, perm2Id],
path: this.resolvePath(
`src/permissions/${this.contractName1}.permissions.ts`
),
},
])
}
protected static async passesThroughDependentSkills() {
const namespace = this.addRandomDependency()
let passedTarget: ListPermContractsTargetAndPayload['target']
await this.eventFaker.fakeListPermissionContracts(({ target }) => {
passedTarget = target
})
await this.fetchContracts()
assert.isEqualDeep(passedTarget, {
namespaces: [namespace],
})
}
protected static async returnsDependencyMapFromRemoteContracts() {
const perm = this.generatePermValues()
const perm2 = this.generatePermValues()
const perm3 = this.generatePermValues()
const { contract, contractId } = this.generateContractRowValues([
perm,
perm2,
])
const { contract: contract2, contractId: contractId2 } =
this.generateContractRowValues([perm3])
await this.eventFaker.fakeListPermissionContracts(() => {
return [contract, contract2]
})
const map = await this.fetchContracts()
//@ts-ignore
assert.isEqualDeep(map, {
[contractId]: [perm.id, perm2.id],
[contractId2]: [perm3.id],
[this.fqid2]: ['can-high-five'],
[buildPermissionContractId('oeu-aoeuao', this.namespace)]: [
'what-the',
'go-dogs',
],
})
}
protected static async connectsAsSkill() {
let passedOptions: ApiClientFactoryOptions | undefined
//@ts-ignore
const old = this.permissions.connectToApi.bind(this.permissions)
//@ts-ignore
this.permissions.connectToApi = (options) => {
passedOptions = options
return old(passedOptions)
}
await this.fetchContracts()
assert.isEqualDeep(passedOptions, { shouldAuthAsCurrentSkill: true })
}
private static updateFirstContractBuilder(
contractId: string,
perm1Id: string,
perm2Id: string
) {
const file = this.resolvePath(
'src',
'permissions',
`${this.contractName1}.permissions.ts`
)
diskUtil.writeFile(
file,
generateContractBuilder(contractId, perm1Id, perm2Id)
)
}
private static generateContractRowValues(
permissions: SpruceSchemas.Mercury.v2020_12_25.Permission[]
) {
const contractId = generateId()
const contract = {
id: generateId(),
contract: {
id: contractId,
name: generateId(),
permissions,
},
}
return { contract, contractId }
}
private static generatePermValues() {
const permissionId = generateId()
const perm = {
id: permissionId,
name: generateId(),
defaults: {},
}
return perm
}
private static addRandomDependency() {
const dep = this.Service('dependency')
const namespace = generateId()
dep.add({
id: generateId(),
namespace,
})
return namespace
}
private static async fetchContracts() {
return this.permissions.fetchContracts()
}
private static async assertLocalPermissionsEqual(
expected: ImportedPermission[]
) {
const perms = await this.loadLocalPermissions()
perms.sort(sortPermissionContracts)
expected.sort(sortPermissionContracts)
assert.isEqualDeep(perms, expected)
}
private static async loadLocalPermissions() {
//@ts-ignore
return await this.permissions.loadLocalPermissions()
}
}
function buildPermissionContractId(
contractId: string,
namespace?: string
): string {
return `${namespace}.${contractId}`
}
function generateContractBuilder(
contractId = 'oeu-aoeuao',
perm1Id = 'what-the',
perm2Id = 'go-dogs'
) {
return `import {
buildPermissionContract
} from '@sprucelabs/mercury-types'
const debeePermissions = buildPermissionContract({
id: '${contractId}',
name: 'debee',
description: '',
requireAllPermissions: false,
permissions: [
{
id: '${perm1Id}',
name: 'Can give high five',
description: 'Will this person be allowed to high five?',
defaults: {
skill: false,
},
requireAllStatuses: false,
},
{
id: '${perm2Id}',
name: 'Can give high five',
description: 'Will this person be allowed to high five?',
defaults: {
skill: false,
},
requireAllStatuses: false,
}
]
})
export default debeePermissions
`
}