mirror of
https://github.com/Cameri/nostream.git
synced 2025-03-29 11:12:20 +01:00
test: improve coverage
This commit is contained in:
parent
b14cbce871
commit
8451b14c16
@ -13,7 +13,7 @@ import { ReplaceableEventStrategy } from '../handlers/event-strategies/replaceab
|
||||
|
||||
export const eventStrategyFactory = (
|
||||
eventRepository: IEventRepository,
|
||||
): Factory<IEventStrategy<Event, Promise<boolean>>, [Event, IWebSocketAdapter]> =>
|
||||
): Factory<IEventStrategy<Event, Promise<void>>, [Event, IWebSocketAdapter]> =>
|
||||
([event, adapter]: [Event, IWebSocketAdapter]) => {
|
||||
if (isReplaceableEvent(event)) {
|
||||
return new ReplaceableEventStrategy(adapter, eventRepository)
|
||||
@ -22,7 +22,7 @@ export const eventStrategyFactory = (
|
||||
} else if (isNullEvent(event)) {
|
||||
return new NullEventStrategy()
|
||||
} else if (isDeleteEvent(event)) {
|
||||
return new DeleteEventStrategy(eventRepository)
|
||||
return new DeleteEventStrategy(adapter, eventRepository)
|
||||
}
|
||||
|
||||
return new DefaultEventStrategy(adapter, eventRepository)
|
||||
|
@ -13,22 +13,17 @@ export class DeleteEventStrategy implements IEventStrategy<Event, Promise<void>>
|
||||
) { }
|
||||
|
||||
public async execute(event: Event): Promise<void> {
|
||||
await this.eventRepository.create(event)
|
||||
|
||||
const eTags = event.tags.filter((tag) => tag[0] === EventTags.Event)
|
||||
|
||||
if (!eTags.length) {
|
||||
return
|
||||
if (eTags.length) {
|
||||
await this.eventRepository.deleteByPubkeyAndIds(
|
||||
event.pubkey,
|
||||
eTags.map((tag) => tag[1])
|
||||
)
|
||||
}
|
||||
|
||||
const count = await this.eventRepository.create(event)
|
||||
if (!count) {
|
||||
return
|
||||
}
|
||||
|
||||
await this.eventRepository.deleteByPubkeyAndIds(
|
||||
event.pubkey,
|
||||
eTags.map((tag) => tag[1])
|
||||
)
|
||||
this.webSocket.emit(WebSocketAdapterEvent.Broadcast, event)
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -0,0 +1,105 @@
|
||||
import chai from 'chai'
|
||||
import chaiAsPromised from 'chai-as-promised'
|
||||
import Sinon from 'sinon'
|
||||
|
||||
chai.use(chaiAsPromised)
|
||||
|
||||
import { DatabaseClient } from '../../../../src/@types/base'
|
||||
import { DeleteEventStrategy } from '../../../../src/handlers/event-strategies/delete-event-strategy'
|
||||
import { Event } from '../../../../src/@types/event'
|
||||
import { EventRepository } from '../../../../src/repositories/event-repository'
|
||||
import { EventTags } from '../../../../src/constants/base'
|
||||
import { IEventRepository } from '../../../../src/@types/repositories'
|
||||
import { IEventStrategy } from '../../../../src/@types/message-handlers'
|
||||
import { IWebSocketAdapter } from '../../../../src/@types/adapters'
|
||||
import { WebSocketAdapterEvent } from '../../../../src/constants/adapter'
|
||||
|
||||
const { expect } = chai
|
||||
|
||||
describe('DeleteEventStrategy', () => {
|
||||
const event: Event = {
|
||||
pubkey: 'pubkey',
|
||||
tags: [
|
||||
[EventTags.Event, 'event id 1'],
|
||||
[EventTags.Event, 'event id 2'],
|
||||
],
|
||||
} as any
|
||||
let webSocket: IWebSocketAdapter
|
||||
let eventRepository: IEventRepository
|
||||
|
||||
let webSocketEmitStub: Sinon.SinonStub
|
||||
let eventRepositoryCreateStub: Sinon.SinonStub
|
||||
let eventRepositoryDeleteByPubkeyAndIdsStub: Sinon.SinonStub
|
||||
|
||||
let strategy: IEventStrategy<Event, Promise<void>>
|
||||
|
||||
let sandbox: Sinon.SinonSandbox
|
||||
|
||||
beforeEach(() => {
|
||||
sandbox = Sinon.createSandbox()
|
||||
|
||||
eventRepositoryCreateStub = sandbox.stub(EventRepository.prototype, 'create')
|
||||
eventRepositoryDeleteByPubkeyAndIdsStub = sandbox.stub(EventRepository.prototype, 'deleteByPubkeyAndIds')
|
||||
|
||||
webSocketEmitStub = sandbox.stub()
|
||||
webSocket = {
|
||||
emit: webSocketEmitStub,
|
||||
} as any
|
||||
const client: DatabaseClient = {} as any
|
||||
eventRepository = new EventRepository(client)
|
||||
|
||||
strategy = new DeleteEventStrategy(webSocket, eventRepository)
|
||||
})
|
||||
|
||||
afterEach(() => {
|
||||
sandbox.restore()
|
||||
})
|
||||
|
||||
describe('execute', () => {
|
||||
it('creates event', async () => {
|
||||
await strategy.execute(event)
|
||||
|
||||
expect(eventRepositoryCreateStub).to.have.been.calledOnceWithExactly(event)
|
||||
})
|
||||
|
||||
it('deletes events if it has e tags', async () => {
|
||||
await strategy.execute(event)
|
||||
|
||||
expect(eventRepositoryDeleteByPubkeyAndIdsStub).to.have.been.calledOnceWithExactly(
|
||||
event.pubkey,
|
||||
['event id 1', 'event id 2'],
|
||||
)
|
||||
})
|
||||
|
||||
it('does not delete events if there are no e tags', async () => {
|
||||
event.tags = []
|
||||
|
||||
await strategy.execute(event)
|
||||
|
||||
expect(eventRepositoryDeleteByPubkeyAndIdsStub).not.to.have.been.called
|
||||
})
|
||||
|
||||
it('broadcast event', async () => {
|
||||
eventRepositoryCreateStub.resolves()
|
||||
|
||||
await strategy.execute(event)
|
||||
|
||||
expect(eventRepositoryCreateStub).to.have.been.calledOnceWithExactly(event)
|
||||
expect(webSocketEmitStub).to.have.been.calledOnceWithExactly(
|
||||
WebSocketAdapterEvent.Broadcast,
|
||||
event
|
||||
)
|
||||
})
|
||||
|
||||
it('rejects if unable to create event', async () => {
|
||||
const error = new Error()
|
||||
eventRepositoryCreateStub.rejects(error)
|
||||
|
||||
await expect(strategy.execute(event)).to.eventually.be.rejectedWith(error)
|
||||
|
||||
expect(eventRepositoryCreateStub).to.have.been.calledOnceWithExactly(event)
|
||||
expect(eventRepositoryDeleteByPubkeyAndIdsStub).not.to.have.been.called
|
||||
expect(webSocketEmitStub).not.to.have.been.called
|
||||
})
|
||||
})
|
||||
})
|
@ -0,0 +1,48 @@
|
||||
import chai from 'chai'
|
||||
import chaiAsPromised from 'chai-as-promised'
|
||||
import Sinon from 'sinon'
|
||||
|
||||
chai.use(chaiAsPromised)
|
||||
|
||||
import { EphemeralEventStrategy } from '../../../../src/handlers/event-strategies/ephemeral-event-strategy'
|
||||
import { Event } from '../../../../src/@types/event'
|
||||
import { IEventStrategy } from '../../../../src/@types/message-handlers'
|
||||
import { IWebSocketAdapter } from '../../../../src/@types/adapters'
|
||||
import { WebSocketAdapterEvent } from '../../../../src/constants/adapter'
|
||||
|
||||
const { expect } = chai
|
||||
|
||||
describe('EphemeralEventStrategy', () => {
|
||||
const event: Event = {} as any
|
||||
let webSocket: IWebSocketAdapter
|
||||
let strategy: IEventStrategy<Event, Promise<void>>
|
||||
let sandbox: Sinon.SinonSandbox
|
||||
|
||||
let webSocketEmitStub: Sinon.SinonStub
|
||||
|
||||
beforeEach(() => {
|
||||
sandbox = Sinon.createSandbox()
|
||||
|
||||
webSocketEmitStub = sandbox.stub()
|
||||
webSocket = {
|
||||
emit: webSocketEmitStub,
|
||||
} as any
|
||||
|
||||
strategy = new EphemeralEventStrategy(webSocket)
|
||||
})
|
||||
|
||||
afterEach(() => {
|
||||
sandbox.restore()
|
||||
})
|
||||
|
||||
describe('execute', () => {
|
||||
it('broadcasts event', async () => {
|
||||
await strategy.execute(event)
|
||||
|
||||
expect(webSocketEmitStub).to.have.been.calledOnceWithExactly(
|
||||
WebSocketAdapterEvent.Broadcast,
|
||||
event
|
||||
)
|
||||
})
|
||||
})
|
||||
})
|
@ -0,0 +1,78 @@
|
||||
import chai from 'chai'
|
||||
import chaiAsPromised from 'chai-as-promised'
|
||||
import Sinon from 'sinon'
|
||||
|
||||
chai.use(chaiAsPromised)
|
||||
|
||||
import { DatabaseClient } from '../../../../src/@types/base'
|
||||
import { Event } from '../../../../src/@types/event'
|
||||
import { EventRepository } from '../../../../src/repositories/event-repository'
|
||||
import { IEventRepository } from '../../../../src/@types/repositories'
|
||||
import { IEventStrategy } from '../../../../src/@types/message-handlers'
|
||||
import { IWebSocketAdapter } from '../../../../src/@types/adapters'
|
||||
import { ReplaceableEventStrategy } from '../../../../src/handlers/event-strategies/replaceable-event-strategy'
|
||||
import { WebSocketAdapterEvent } from '../../../../src/constants/adapter'
|
||||
|
||||
const { expect } = chai
|
||||
|
||||
describe('ReplaceableEventStrategy', () => {
|
||||
const event: Event = {} as any
|
||||
let webSocket: IWebSocketAdapter
|
||||
let eventRepository: IEventRepository
|
||||
|
||||
let webSocketEmitStub: Sinon.SinonStub
|
||||
let eventRepositoryUpsertStub: Sinon.SinonStub
|
||||
|
||||
let strategy: IEventStrategy<Event, Promise<void>>
|
||||
|
||||
let sandbox: Sinon.SinonSandbox
|
||||
|
||||
beforeEach(() => {
|
||||
sandbox = Sinon.createSandbox()
|
||||
|
||||
eventRepositoryUpsertStub = sandbox.stub(EventRepository.prototype, 'upsert')
|
||||
|
||||
webSocketEmitStub = sandbox.stub()
|
||||
webSocket = {
|
||||
emit: webSocketEmitStub,
|
||||
} as any
|
||||
const client: DatabaseClient = {} as any
|
||||
eventRepository = new EventRepository(client)
|
||||
|
||||
strategy = new ReplaceableEventStrategy(webSocket, eventRepository)
|
||||
})
|
||||
|
||||
afterEach(() => {
|
||||
sandbox.restore()
|
||||
})
|
||||
|
||||
describe('execute', () => {
|
||||
it('upserts event', async () => {
|
||||
await strategy.execute(event)
|
||||
|
||||
expect(eventRepositoryUpsertStub).to.have.been.calledOnceWithExactly(event)
|
||||
})
|
||||
|
||||
it('broadcast event if event is created', async () => {
|
||||
eventRepositoryUpsertStub.resolves(1)
|
||||
|
||||
await strategy.execute(event)
|
||||
|
||||
expect(eventRepositoryUpsertStub).to.have.been.calledOnceWithExactly(event)
|
||||
expect(webSocketEmitStub).to.have.been.calledOnceWithExactly(
|
||||
WebSocketAdapterEvent.Broadcast,
|
||||
event
|
||||
)
|
||||
})
|
||||
|
||||
it('rejects if unable to upsert event', async () => {
|
||||
const error = new Error()
|
||||
eventRepositoryUpsertStub.rejects(error)
|
||||
|
||||
await expect(strategy.execute(event)).to.eventually.be.rejectedWith(error)
|
||||
|
||||
expect(eventRepositoryUpsertStub).to.have.been.calledOnceWithExactly(event)
|
||||
expect(webSocketEmitStub).not.to.have.been.called
|
||||
})
|
||||
})
|
||||
})
|
347
test/unit/utils/runes.spec.ts
Normal file
347
test/unit/utils/runes.spec.ts
Normal file
@ -0,0 +1,347 @@
|
||||
import { expect } from 'chai'
|
||||
import sinon from 'sinon'
|
||||
|
||||
import { Alternative } from '../../../src/utils/runes/alternative'
|
||||
import { Restriction } from '../../../src/utils/runes/restriction'
|
||||
|
||||
describe('Alternative', () => {
|
||||
describe('constructor', () => {
|
||||
it('throw error if field has punctuations', () => {
|
||||
expect(() => new Alternative('%', '=', 'value')).to.throw(Error, 'Field is not valid')
|
||||
})
|
||||
|
||||
it('throw error if cond is not valid', () => {
|
||||
expect(() => new Alternative('field', '@', 'value')).to.throw(Error, 'Cond is not valid')
|
||||
})
|
||||
|
||||
it('returns an Alternative if given valid fields', () => {
|
||||
expect(new Alternative('field', '=', 'value')).to.be.an.instanceOf(Alternative)
|
||||
})
|
||||
})
|
||||
|
||||
describe('test', () => {
|
||||
it('returns undefined always if rule is #', () => {
|
||||
expect(new Alternative('', '#', '').test({})).to.be.undefined
|
||||
})
|
||||
|
||||
it('returns reason if field not present with rule field=value', () => {
|
||||
expect(new Alternative('field', '=', 'value').test({})).to.equal('field: is missing')
|
||||
})
|
||||
|
||||
it('returns undefined if field is not present with rule field!', () => {
|
||||
expect(new Alternative('field', '!', '').test({})).to.be.undefined
|
||||
})
|
||||
|
||||
it('returns reason if field is present with rule field!', () => {
|
||||
expect(new Alternative('field', '!', '').test({ field: 'value' })).to.equal('field: is present')
|
||||
})
|
||||
|
||||
it('calls function if field is a function', () => {
|
||||
const spy = sinon.fake.returns('reason')
|
||||
const alternative = new Alternative('field', '=', 'value')
|
||||
|
||||
const result = alternative.test({ field: spy })
|
||||
|
||||
expect(spy).to.have.been.calledOnceWithExactly(alternative)
|
||||
expect(result).to.equal('reason')
|
||||
})
|
||||
|
||||
it('returns reason if field not equals value with rule field=value', () => {
|
||||
expect(new Alternative('field', '=', 'value').test({ field: 'not value' })).to.equal('field: != value')
|
||||
})
|
||||
|
||||
it('returns undefined if field equals value with rule field=value', () => {
|
||||
expect(new Alternative('field', '=', 'value').test({ field: 'value' })).to.be.undefined
|
||||
})
|
||||
|
||||
it('returns undefined if field not equals value with rule field/value', () => {
|
||||
expect(new Alternative('field', '/', 'value').test({ field: 'not value' })).to.be.undefined
|
||||
})
|
||||
|
||||
it('returns reason if field equals value with rule field/value', () => {
|
||||
expect(new Alternative('field', '/', 'value').test({ field: 'value' })).to.equal('field: = value')
|
||||
})
|
||||
|
||||
it('returns undefined if field starts with value with rule field^value', () => {
|
||||
expect(new Alternative('field', '^', 'value').test({ field: 'value <- here' })).to.be.undefined
|
||||
})
|
||||
|
||||
it('returns reason if field does not start value with rule field^value', () => {
|
||||
expect(new Alternative('field', '^', 'value').test({ field: 'nope' })).to.equal('field: does not start with value')
|
||||
})
|
||||
|
||||
it('returns undefined if field ends with value with rule field$value', () => {
|
||||
expect(new Alternative('field', '$', 'value').test({ field: 'ends -> value' })).to.be.undefined
|
||||
})
|
||||
|
||||
it('returns reason if field does not end value with rule field$value', () => {
|
||||
expect(new Alternative('field', '$', 'value').test({ field: 'nope' })).to.equal('field: does not end with value')
|
||||
})
|
||||
|
||||
it('returns undefined if field contains value with in string rule field~value', () => {
|
||||
expect(new Alternative('field', '~', 'value').test({ field: '-> value <-' })).to.be.undefined
|
||||
})
|
||||
|
||||
it('returns reason if field does not contain value in string with rule field~value', () => {
|
||||
expect(new Alternative('field', '~', 'value').test({ field: 'nope' })).to.equal('field: does not contain value')
|
||||
})
|
||||
|
||||
it('returns undefined if field contains value in array with rule field~value', () => {
|
||||
expect(new Alternative('field', '~', 'value').test({ field: ['value'] })).to.be.undefined
|
||||
})
|
||||
|
||||
it('returns reason if field does not contain value in array with rule field~value', () => {
|
||||
expect(new Alternative('field', '~', 'value').test({ field: [] })).to.equal('field: does not contain value')
|
||||
})
|
||||
|
||||
|
||||
|
||||
|
||||
it('returns undefined if field is less than value with rule field<value', () => {
|
||||
expect(new Alternative('field', '<', '0').test({ field: -1 })).to.be.undefined
|
||||
})
|
||||
|
||||
it('returns reason if field does not less than value with rule field<value', () => {
|
||||
expect(new Alternative('field', '<', '0').test({ field: 0 })).to.equal('field: >= 0')
|
||||
})
|
||||
|
||||
it('returns undefined if field is greater than value with rule field>value', () => {
|
||||
expect(new Alternative('field', '>', '0').test({ field: 1 })).to.be.undefined
|
||||
})
|
||||
|
||||
it('returns reason if field does not greater than value with rule field>value', () => {
|
||||
expect(new Alternative('field', '>', '0').test({ field: 0 })).to.equal('field: <= 0')
|
||||
})
|
||||
|
||||
it('returns reason if field is not an integer with rule field<value', () => {
|
||||
expect(new Alternative('field', '<', '0').test({ field: 'not an integer' })).to.equal('field: not an integer field')
|
||||
})
|
||||
|
||||
it('returns reason if field is not an integer with rule field>value', () => {
|
||||
expect(new Alternative('field', '>', '0').test({ field: 'not an integer' })).to.equal('field: not an integer field')
|
||||
})
|
||||
|
||||
it('returns reason if field is not an integer with rule field<value', () => {
|
||||
expect(new Alternative('field', '<', 'not an integer').test({ field: 1 })).to.equal('field: not a valid integer')
|
||||
})
|
||||
|
||||
it('returns reason if field is not an integer with rule field>value', () => {
|
||||
expect(new Alternative('field', '>', 'not an integer').test({ field: 1 })).to.equal('field: not a valid integer')
|
||||
})
|
||||
|
||||
|
||||
|
||||
it('returns undefined if field is same as value with rule field{value', () => {
|
||||
expect(new Alternative('field', '{', 'b').test({ field: 'b' })).to.equal('field: is the same or ordered after b')
|
||||
})
|
||||
|
||||
it('returns undefined if field is ordered before value with rule field{value', () => {
|
||||
expect(new Alternative('field', '{', 'b').test({ field: 'a' })).to.be.undefined
|
||||
})
|
||||
|
||||
it('returns reason if field is ordered after value with rule field{value', () => {
|
||||
expect(new Alternative('field', '{', 'b').test({ field: 'c' })).to.equal('field: is the same or ordered after b')
|
||||
})
|
||||
|
||||
it('returns undefined if field is same as value with rule field}value', () => {
|
||||
expect(new Alternative('field', '}', 'b').test({ field: 'b' })).to.equal('field: is the same or ordered before b')
|
||||
})
|
||||
|
||||
it('returns undefined if field is ordered after value with rule field}value', () => {
|
||||
expect(new Alternative('field', '}', 'b').test({ field: 'c' })).to.be.undefined
|
||||
})
|
||||
|
||||
it('returns reason if field is ordered before value with rule field}value', () => {
|
||||
expect(new Alternative('field', '}', 'b').test({ field: 'a' })).to.equal('field: is the same or ordered before b')
|
||||
})
|
||||
})
|
||||
|
||||
describe('encode', () => {
|
||||
it('returns encoded alternative field = value', () => {
|
||||
expect(new Alternative('field', '=', 'value').encode()).to.equal('field=value')
|
||||
})
|
||||
|
||||
it('returns encoded alternative #', () => {
|
||||
expect(new Alternative('', '#', '').encode()).to.equal('#')
|
||||
})
|
||||
|
||||
it('returns encoded alternative field!', () => {
|
||||
expect(new Alternative('field', '!', '').encode()).to.equal('field!')
|
||||
})
|
||||
|
||||
it('returns encoded alternative field=\\|&', () => {
|
||||
expect(new Alternative('field', '=', '\\|&').encode()).to.equal('field=\\\\\\|\\&')
|
||||
})
|
||||
})
|
||||
|
||||
describe('decode', () => {
|
||||
it('decodes #', () => {
|
||||
const [alternative] = Alternative.decode('#')
|
||||
expect(alternative.encode()).to.equal('#')
|
||||
})
|
||||
|
||||
it('decodes field!', () => {
|
||||
const [alternative] = Alternative.decode('field!')
|
||||
expect(alternative.encode()).to.equal('field!')
|
||||
})
|
||||
|
||||
it('decodes field=value', () => {
|
||||
const [alternative] = Alternative.decode('field=value')
|
||||
expect(alternative.encode()).to.equal('field=value')
|
||||
})
|
||||
|
||||
it('decodes field=\\\\\\|\\&', () => {
|
||||
const [alternative] = Alternative.decode('field=\\\\\\|\\&')
|
||||
expect(alternative.encode()).to.equal('field=\\\\\\|\\&')
|
||||
})
|
||||
|
||||
it('throw error decoding value', () => {
|
||||
expect(() => Alternative.decode('value')).to.throw(Error, 'value does not contain any operator')
|
||||
})
|
||||
|
||||
it('decodes until first | and consumes it', () => {
|
||||
const [alternative, remainder] = Alternative.decode('a=1|b=2')
|
||||
expect(alternative.encode()).to.equal('a=1')
|
||||
expect(remainder).to.equal('b=2')
|
||||
})
|
||||
|
||||
it('decodes until first &', () => {
|
||||
const [alternative, remainder] = Alternative.decode('a=1&b=2')
|
||||
expect(alternative.encode()).to.equal('a=1')
|
||||
expect(remainder).to.equal('&b=2')
|
||||
})
|
||||
})
|
||||
|
||||
describe('from', () => {
|
||||
it('creates alternative rule with spaces "field = value"', () => {
|
||||
expect(Alternative.from('field = value').encode()).to.equal('field=value')
|
||||
})
|
||||
})
|
||||
})
|
||||
|
||||
describe('Restriction', () => {
|
||||
describe('constructor', () => {
|
||||
it('throws if given alternatives list is empty', () => [
|
||||
expect(() => new Restriction([])).to.throw(Error, 'Restriction must have some alternatives'),
|
||||
])
|
||||
})
|
||||
|
||||
describe('test', () => {
|
||||
it('returns undefined given 1 true alternative', () => {
|
||||
const values = { a: 1 }
|
||||
const alternatives: Alternative[] = [
|
||||
{ test: sinon.fake.returns(undefined) },
|
||||
] as any
|
||||
|
||||
expect(new Restriction(alternatives).test(values)).to.be.undefined
|
||||
|
||||
expect(alternatives[0].test).to.have.been.calledOnceWithExactly(values)
|
||||
})
|
||||
|
||||
it('returns undefined given 2 true alternative', () => {
|
||||
const values = { a: 1 }
|
||||
const alternatives: Alternative[] = [
|
||||
{ test: sinon.fake.returns(undefined) },
|
||||
{ test: sinon.fake.returns(undefined) },
|
||||
] as any
|
||||
|
||||
expect(new Restriction(alternatives).test(values)).to.be.undefined
|
||||
|
||||
expect(alternatives[0].test).to.have.been.calledOnceWithExactly(values)
|
||||
expect(alternatives[1].test).not.to.have.been.called
|
||||
})
|
||||
|
||||
it('returns undefined given 1 true and 1 false alternative', () => {
|
||||
const values = { a: 1 }
|
||||
const alternatives: Alternative[] = [
|
||||
{ test: sinon.fake.returns(undefined) },
|
||||
{ test: sinon.fake.returns('reason') },
|
||||
] as any
|
||||
|
||||
expect(new Restriction(alternatives).test(values)).to.be.undefined
|
||||
|
||||
expect(alternatives[0].test).to.have.been.calledOnceWithExactly(values)
|
||||
expect(alternatives[1].test).not.to.have.been.called
|
||||
})
|
||||
|
||||
it('returns reason given 1 false alternative', () => {
|
||||
const values = { a: 1 }
|
||||
const alternatives: Alternative[] = [
|
||||
{ test: sinon.fake.returns('reason') },
|
||||
] as any
|
||||
|
||||
expect(new Restriction(alternatives).test(values)).to.equal('reason')
|
||||
|
||||
expect(alternatives[0].test).to.have.been.calledOnceWithExactly(values)
|
||||
})
|
||||
|
||||
it('returns undefined given 1 false and 1 true alternative', () => {
|
||||
const values = { a: 1 }
|
||||
const alternatives: Alternative[] = [
|
||||
{ test: sinon.fake.returns('reason') },
|
||||
{ test: sinon.fake.returns(undefined) },
|
||||
] as any
|
||||
|
||||
expect(new Restriction(alternatives).test(values)).to.be.undefined
|
||||
|
||||
expect(alternatives[0].test).to.have.been.calledOnceWithExactly(values)
|
||||
expect(alternatives[1].test).to.have.been.calledOnceWithExactly(values)
|
||||
})
|
||||
|
||||
it('returns reasons given 2 false alternatives', () => {
|
||||
const values = { a: 1 }
|
||||
const alternatives: Alternative[] = [
|
||||
{ test: sinon.fake.returns('reason 1') },
|
||||
{ test: sinon.fake.returns('reason 2') },
|
||||
] as any
|
||||
|
||||
expect(new Restriction(alternatives).test(values)).to.equal('reason 1 AND reason 2')
|
||||
|
||||
expect(alternatives[0].test).to.have.been.calledOnceWithExactly(values)
|
||||
expect(alternatives[1].test).to.have.been.calledOnceWithExactly(values)
|
||||
})
|
||||
})
|
||||
|
||||
describe('encode', () => {
|
||||
it('returns encoded restriction with 1 alternative', () => {
|
||||
const alternatives: Alternative[] = [
|
||||
{ encode: sinon.fake.returns('a=1') },
|
||||
] as any
|
||||
|
||||
expect(new Restriction(alternatives).encode()).to.equal('a=1')
|
||||
})
|
||||
|
||||
|
||||
it('returns encoded restrictions with 2 alternatives', () => {
|
||||
const alternatives: Alternative[] = [
|
||||
{ encode: sinon.fake.returns('a=1') },
|
||||
{ encode: sinon.fake.returns('b=2') },
|
||||
] as any
|
||||
|
||||
expect(new Restriction(alternatives).encode()).to.equal('a=1|b=2')
|
||||
})
|
||||
})
|
||||
|
||||
describe('decode', () => {
|
||||
it('returns encoded restriction given 1 alternative', () => {
|
||||
const [restriction, remainder] = Restriction.decode('a=1')
|
||||
|
||||
expect(restriction.encode()).to.equal('a=1')
|
||||
expect(remainder).to.be.empty
|
||||
})
|
||||
|
||||
it('returns encoded restriction given 2 alternatives', () => {
|
||||
const [restriction, remainder] = Restriction.decode('a=1|b=2')
|
||||
|
||||
expect(restriction.encode()).to.equal('a=1|b=2')
|
||||
expect(remainder).to.be.empty
|
||||
})
|
||||
|
||||
it('returns encoded restriction given 2 alternatives and another restriction', () => {
|
||||
const [restriction, remainder] = Restriction.decode('a=1|b=2&c=1')
|
||||
|
||||
expect(restriction.encode()).to.equal('a=1|b=2')
|
||||
expect(remainder).to.equal('c=1')
|
||||
})
|
||||
})
|
||||
})
|
Loading…
x
Reference in New Issue
Block a user