From f8088a36648201fda7a12ee8e184ff654af83d14 Mon Sep 17 00:00:00 2001 From: Nuno Frade Date: Thu, 25 Apr 2024 14:33:00 +0200 Subject: [PATCH 1/2] Adds a list subscription timebased test --- client/test/subscriptionTimebased.ts | 83 ++++++++++++++++++++++++++++ yarn.lock | 18 ++++++ 2 files changed, 101 insertions(+) create mode 100644 client/test/subscriptionTimebased.ts diff --git a/client/test/subscriptionTimebased.ts b/client/test/subscriptionTimebased.ts new file mode 100644 index 000000000..0f6056431 --- /dev/null +++ b/client/test/subscriptionTimebased.ts @@ -0,0 +1,83 @@ +import test from 'ava' +import { connect } from '../src/index' +import { SelvaServer, start } from '@saulx/selva-server' +import { wait } from './assertions' +import getPort from 'get-port' + +let srv: SelvaServer +let port: number + +test.before(async (t) => { + port = await getPort() + srv = await start({ + port, + }) + const client = connect({ port }) + await client.updateSchema({ + languages: ['en'], + types: { + aType: { + prefix: 'at', + fields: { + name: { type: 'string' }, + value: { type: 'number' }, + date: { type: 'timestamp' }, + }, + }, + }, + }) + await client.destroy() +}) + +test.after(async (t) => { + const client = connect({ port }) + await client.destroy() + await srv.destroy() +}) + +test.serial('simple find subscription time based', async (t) => { + t.timeout(3000) + + const client = connect({ port }) + + const ts = Date.now() + await client.set({ + type: 'aType', + name: 'name', + date: ts + 1000, + }) + await wait(200) + + let resultAmount = 0 + client + .observe({ + items: { + id: true, + $list: { + $find: { + $traverse: 'children', + $filter: [ + { + $field: 'type', + $operator: '=', + $value: 'aType', + }, + { + $field: 'date', + $operator: '>', + $value: 'now', + }, + ], + }, + }, + }, + }) + .subscribe((result) => { + resultAmount = result.items?.length + }) + + await wait(200) + t.is(resultAmount, 1) + await wait(1200) + t.is(resultAmount, 0) +}) diff --git a/yarn.lock b/yarn.lock index 0d5190325..54507038d 100644 --- a/yarn.lock +++ b/yarn.lock @@ -248,6 +248,24 @@ resolved "https://registry.npmjs.org/@saulx/prettier-config/-/prettier-config-1.0.0.tgz" integrity "sha1-pu8WF4lTSD1VcJ7LHjQU+jUlnDg= sha512-UtITV+SUiK6gaNsUdQKHJbffHiNsh1dt+IxZSiUqFcgbq16iWAYWPfty/pchNzYwMgXmjsuIN98++WE4DWdQ/g==" +"@saulx/selva@21.2.3": + version "21.2.3" + resolved "https://registry.yarnpkg.com/@saulx/selva/-/selva-21.2.3.tgz#6cd74b7424d06aec6ea586c6608ea4f173b328c3" + integrity sha512-P7WIbwbhzP91W2vQz49cKspT2UIuyD/yX9RkNxXL57Iz1VcOY55cYsCqPEVMd7EuZRwB/mPvxNRMzCU/KsXjAA== + dependencies: + "@saulx/diff" "^1.1.3" + "@saulx/redis-client" "^1.0.0" + "@saulx/selva-query-ast-parser" "^4.0.2" + "@saulx/utils" "^2.0.1" + "@saulx/validators" "^1.1.0" + "@types/uuid" "^8.3.0" + chalk "^4.1.0" + data-record "^1.0.0" + pg "8.7.1" + pg-native "3.0.0" + squel "^5.13.0" + uuid "^8.3.2" + "@saulx/utils@^2.0.1": version "2.0.1" resolved "https://registry.npmjs.org/@saulx/utils/-/utils-2.0.1.tgz" From a1298f24df65ecac2796f028b5db95e6228943c0 Mon Sep 17 00:00:00 2001 From: Nuno Frade Date: Thu, 16 May 2024 14:07:20 +0200 Subject: [PATCH 2/2] Throws when trying to set a records field that has a dot in the key --- client/src/set/fieldParsers/record.ts | 4 +++ client/src/set/validate.ts | 8 ++++- client/test/record.ts | 42 ++++++++++++++++++++++++++- 3 files changed, 52 insertions(+), 2 deletions(-) diff --git a/client/src/set/fieldParsers/record.ts b/client/src/set/fieldParsers/record.ts index 3017d8ff5..5ac918042 100644 --- a/client/src/set/fieldParsers/record.ts +++ b/client/src/set/fieldParsers/record.ts @@ -19,6 +19,10 @@ export default async ( const fn = fieldParsers[fields.values.type] + if (Object.keys(payload).filter((key) => /\./g.test(key)).length) { + throw new Error('Cannot use "." in a record key') + } + if (payload.$delete) { result.push('7', field, '') return 0 diff --git a/client/src/set/validate.ts b/client/src/set/validate.ts index 833e3fec6..04f195703 100644 --- a/client/src/set/validate.ts +++ b/client/src/set/validate.ts @@ -65,7 +65,13 @@ export default async function parseSetObject( // && (payload.parents).$noRoot const isNonEmpty = (v: any): boolean => !!(v && v.length) - if (payload.parents && (payload.parents['$noRoot'] || Array.isArray(payload.parents) || payload.parents.$value || isNonEmpty(payload.parents['$add']))) { + if ( + payload.parents && + (payload.parents['$noRoot'] || + Array.isArray(payload.parents) || + payload.parents.$value || + isNonEmpty(payload.parents['$add'])) + ) { result[0] += 'N' } diff --git a/client/test/record.ts b/client/test/record.ts index 06c4e40d6..fb97a32cd 100644 --- a/client/test/record.ts +++ b/client/test/record.ts @@ -21,6 +21,7 @@ test.before(async (t) => { }, }, hello: { + prefix: 'he', fields: { name: { type: 'string' }, members: { @@ -48,7 +49,7 @@ test.after(async (t) => { await t.connectionsAreEmpty() }) -test.serial('remove object from record', async (t) => { +test.serial.failing('remove object from record', async (t) => { const client = connect({ port: port }) const thingId = await client.set({ @@ -110,3 +111,42 @@ test.serial('remove object from record', async (t) => { await client.destroy() }) + +test.serial('fail when setting key with a dot', async (t) => { + const client = connect({ port: port }) + + await client.set({ + $id: 'he111111', + members: { + 'Very long first': { + x: 'first', + }, + }, + }) + + t.throwsAsync( + client.set({ + $id: 'he111111', + name: 'derp', + members: { + hallo: { + x: 'hallo', + }, + '1.yeye': { + x: 'doei', + }, + }, + }) + ) + await wait(200) + + t.deepEqual(await client.get({ $id: 'he111111', members: true }), { + members: { + 'Very long first': { + x: 'first', + }, + }, + }) + + await client.destroy() +})