Skip to content

Commit 97c1dbc

Browse files
committed
e2e - add eventually tests
1 parent 352a388 commit 97c1dbc

File tree

5 files changed

+113
-39
lines changed

5 files changed

+113
-39
lines changed
Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
import * as trier from 'trier-promise'
2+
3+
const defaults = {
4+
timeout: 5000,
5+
interval: 200
6+
}
7+
8+
export const eventually = async (fn: any, opts?: { timeout?: number; interval?: number }) => {
9+
return Promise.resolve().then(() => {
10+
let error = null
11+
const action = () => Promise.resolve().then(fn).catch(err => {
12+
error = err
13+
throw err
14+
})
15+
const options = Object.assign({ action }, defaults, opts)
16+
17+
return trier(options).catch(() => {
18+
if (error !== null) {
19+
error.message = `Timeout of ${options.timeout} ms with: ` + error.message
20+
}
21+
throw error
22+
})
23+
})
24+
}
Lines changed: 17 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -1,25 +1,13 @@
1-
import { IndexFieldOrder, IndexStatus } from "libs/velo-external-db-core/src/spi-model/indexing";
2-
3-
// const responseWith = (matcher: any) => expect.objectContaining({ data: matcher })
1+
import { IndexFieldOrder, IndexStatus, Index } from "libs/velo-external-db-core/src/spi-model/indexing";
42

3+
const responseWith = (matcher: any) => expect.objectContaining({ data: matcher })
54

65
export const listIndexResponseWithDefaultIndex = () =>
76
expect.arrayContaining([toHaveDefaultIndex()])
87

9-
// export const listIndexResponseWith = (indexes: any) =>
10-
// expect.arrayContaining(
11-
// [...indexes.map((index: any) => expect.objectContaining({
12-
// ...index,
13-
// status: IndexStatus.ACTIVE
14-
// }))]
15-
// )
16-
export const listIndexResponseWith = (indexes: any) =>
8+
export const listIndexResponseWith = (indexes: Index[]) =>
179
expect.arrayContaining(
18-
[...indexes.map((index: any) => ({
19-
...index,
20-
status: IndexStatus.ACTIVE,
21-
caseInsensitive: expect.any(Boolean), // TODO: remove this when we support case insensitive indexes
22-
}))]
10+
[...indexes.map((index: Index) => indexWith(index, { status: IndexStatus.ACTIVE }))]
2311
)
2412

2513
export const toHaveDefaultIndex = () => ({
@@ -36,5 +24,16 @@ export const toHaveDefaultIndex = () => ({
3624
})
3725

3826

39-
// [{"caseInsensitive": false, "fields": [{"order": "ASC", "path": "cebi"}], "name": "dak", "status": 2, "unique": true}]
40-
// {"caseInsensitive": true, "fields": [{"order": "ASC", "path": "cebi"}], "name": "dak", "status": 2, "unique": true}]
27+
export const createIndexResponseWith = (index: Index) => responseWith(({ index: indexWith(index, { status: IndexStatus.BUILDING }) }))
28+
29+
export const removeIndexResponse = () => responseWith(({}))
30+
31+
const indexWith = (index: Index, extraProps: Partial<Index>) => ({
32+
...index,
33+
fields: index.fields.map(field => ({
34+
...field,
35+
order: expect.toBeOneOf([IndexFieldOrder.ASC, IndexFieldOrder.DESC]),
36+
})),
37+
caseInsensitive: expect.any(Boolean), // TODO: remove this when we support case insensitive indexes
38+
...extraProps
39+
})

apps/velo-external-db/test/e2e/app_index.e2e.spec.ts

Lines changed: 68 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ import * as index from '../drivers/index_api_rest_test_support'
88
import * as gen from '../gen'
99
import axios from 'axios'
1010
const chance = new Chance()
11-
import { InputField } from '@wix-velo/velo-external-db-types'
11+
import { eventually } from '../drivers/eventually'
1212

1313
const axiosServer = axios.create({
1414
baseURL: 'http://localhost:8080'
@@ -19,17 +19,17 @@ export const streamToArray = async (stream) => { //todo: move this to utils
1919

2020
return new Promise((resolve, reject) => {
2121
const arr = []
22-
22+
2323
stream.on('data', data => {
2424
arr.push(JSON.parse(data.toString()))
2525
});
26-
26+
2727
stream.on('end', () => {
2828
resolve(arr)
2929
});
3030

3131
stream.on('error', (err) => reject(err))
32-
32+
3333
})
3434
}
3535

@@ -48,22 +48,80 @@ describe(`Velo External DB Index API: ${currentDbImplementationName()}`, () => {
4848

4949
const response = await axiosServer.post('/indexes/list', {
5050
dataCollectionId: ctx.collectionName
51-
}, {responseType: 'stream', ...authOwner})
51+
}, { responseType: 'stream', ...authOwner })
5252

53-
await expect(streamToArray(response.data)).resolves.toEqual(matchers.listIndexResponseWithDefaultIndex())
53+
// expect(streamToArray(response.data)).
54+
expect(streamToArray(response.data)).resolves.toEqual(matchers.listIndexResponseWithDefaultIndex())
5455
})
5556

5657
test('list with multiple indexes', async () => {
5758
await schema.givenCollection(ctx.collectionName, [ctx.column], authOwner)
5859
await index.givenIndexes(ctx.collectionName, [ctx.index], authOwner)
5960

60-
const response = await axiosServer.post('/indexes/list', {
61-
dataCollectionId: ctx.collectionName
62-
}, {responseType: 'stream', ...authOwner})
61+
await eventually(async () => {
62+
const response = await axiosServer.post('/indexes/list', {
63+
dataCollectionId: ctx.collectionName
64+
}, { responseType: 'stream', ...authOwner })
65+
await expect(streamToArray(response.data)).resolves.toEqual(matchers.listIndexResponseWith([ctx.index]))
66+
})
67+
})
6368

64-
await expect(streamToArray(response.data)).resolves.toEqual(matchers.listIndexResponseWith([ctx.index]))
69+
test('create', async () => {
70+
await schema.givenCollection(ctx.collectionName, [ctx.column], authOwner)
71+
72+
// in-progress
73+
await expect(axiosServer.post('/indexes/create', {
74+
dataCollectionId: ctx.collectionName,
75+
index: ctx.index
76+
}, authOwner)).resolves.toEqual(matchers.createIndexResponseWith(ctx.index))
77+
78+
// active
79+
await eventually(async () => {
80+
const response = await axiosServer.post('/indexes/list', {
81+
dataCollectionId: ctx.collectionName
82+
}, { responseType: 'stream', ...authOwner })
83+
await expect(streamToArray(response.data)).resolves.toEqual(matchers.listIndexResponseWith([ctx.index]))
84+
})
6585
})
6686

87+
test('create with existing index', async () => {
88+
await schema.givenCollection(ctx.collectionName, [ctx.column], authOwner)
89+
await index.givenIndexes(ctx.collectionName, [ctx.index], authOwner)
90+
91+
eventually(async () => {
92+
await expect(axiosServer.post('/indexes/create', {
93+
dataCollectionId: ctx.collectionName,
94+
index: ctx.index
95+
}, authOwner)).rejects.toThrow()
96+
}, {
97+
timeout: 5000,
98+
interval: 1000
99+
})
100+
})
101+
102+
test.only('remove', async() => {
103+
await schema.givenCollection(ctx.collectionName, [ctx.column], authOwner)
104+
await index.givenIndexes(ctx.collectionName, [ctx.index], authOwner)
105+
106+
await eventually(async () => {
107+
await expect(axiosServer.post('/indexes/remove', {
108+
dataCollectionId: ctx.collectionName,
109+
indexName: ctx.index.name
110+
}, authOwner)).resolves.toEqual(matchers.removeIndexResponse()).catch()
111+
})
112+
113+
// await expect(axiosServer.post('/indexes/remove', {
114+
// dataCollectionId: ctx.collectionName,
115+
// index: ctx.index
116+
// }, authOwner)).resolves.toEqual(matchers.removeIndexResponse())
117+
118+
// const response = await axiosServer.post('/indexes/list', {
119+
// dataCollectionId: ctx.collectionName
120+
// }, { responseType: 'stream', ...authOwner })
121+
// await expect(streamToArray(response.data)).resolves.not.toEqual(matchers.listIndexResponseWith([ctx.index]))
122+
})
123+
124+
67125
afterAll(async () => {
68126
await teardownApp()
69127
})

libs/velo-external-db-core/src/service/indexing.ts

Lines changed: 3 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -14,16 +14,8 @@ export default class IndexService {
1414

1515
async create(collectionName: string, index: SpiIndex) {
1616
const domainIndex = this.spiIndexToDomainIndex(index)
17-
try {
18-
const createdIndex = await this.storage.create(collectionName, domainIndex)
19-
return this.domainIndexToSpiIndex(createdIndex)
20-
} catch (e: any) {
21-
return {
22-
...index,
23-
status: IndexStatus.FAILED,
24-
error: e.message,
25-
} as SpiIndex
26-
}
17+
const createdIndex = await this.storage.create(collectionName, domainIndex)
18+
return this.domainIndexToSpiIndex(createdIndex)
2719
}
2820

2921
async remove(collectionName: string, indexName: string) {
@@ -41,7 +33,7 @@ export default class IndexService {
4133
}
4234
}
4335

44-
private spiIndexToDomainIndex(spiIndex: SpiIndex): DomainIndex{
36+
private spiIndexToDomainIndex(spiIndex: SpiIndex): DomainIndex {
4537
return {
4638
name: spiIndex.name,
4739
columns: spiIndex.fields.map(field => field.path),

package.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -62,6 +62,7 @@
6262
"pg": "^8.7.3",
6363
"pg-escape": "^0.2.0",
6464
"sqlstring": "^2.3.3",
65+
"trier-promise": "^1.0.1",
6566
"tslib": "^2.3.0",
6667
"tsqlstring": "^1.0.1",
6768
"uuid": "^8.3.2"

0 commit comments

Comments
 (0)