diff --git a/packages/core-app-api/src/apis/implementations/StorageApi/PersistentStorage.test.ts b/packages/core-app-api/src/apis/implementations/StorageApi/PersistentStorage.test.ts index dfa0008e32..3157395bcf 100644 --- a/packages/core-app-api/src/apis/implementations/StorageApi/PersistentStorage.test.ts +++ b/packages/core-app-api/src/apis/implementations/StorageApi/PersistentStorage.test.ts @@ -52,7 +52,7 @@ describe('Persistent Storage API', () => { beforeEach(() => { server.use( - rest.get(`${mockBaseUrl}/`, async (_req, res, ctx) => { + rest.get(`${mockBaseUrl}/buckets/`, async (_req, res, ctx) => { return res(ctx.json([])); }), ); @@ -64,9 +64,12 @@ describe('Persistent Storage API', () => { const storage = createPersistentStorage(); server.use( - rest.get(`${mockBaseUrl}/:bucket/:key`, async (_req, res, ctx) => { - return res(ctx.json({ value: 'a' })); - }), + rest.get( + `${mockBaseUrl}/buckets/:bucket/:key`, + async (_req, res, ctx) => { + return res(ctx.json({ value: 'a' })); + }, + ), ); expect(storage.snapshot('myfakekey').value).toBeUndefined(); @@ -82,7 +85,7 @@ describe('Persistent Storage API', () => { const dummyValue = 'a'; server.use( - rest.put(`${mockBaseUrl}/:bucket/:key`, async (req, res, ctx) => { + rest.put(`${mockBaseUrl}/buckets/:bucket/:key`, async (req, res, ctx) => { const body = await req.json(); const data = { value: JSON.stringify(dummyValue) }; expect(body).toEqual(data); @@ -102,7 +105,7 @@ describe('Persistent Storage API', () => { }; server.use( - rest.put(`${mockBaseUrl}/:bucket/:key`, async (req, res, ctx) => { + rest.put(`${mockBaseUrl}/buckets/:bucket/:key`, async (req, res, ctx) => { const body = await req.json(); const data = { value: JSON.stringify(dummyValue) }; expect(body).toEqual(data); @@ -122,7 +125,7 @@ describe('Persistent Storage API', () => { const mockData = { hello: 'im a great new value' }; server.use( - rest.put(`${mockBaseUrl}/:bucket/:key`, async (req, res, ctx) => { + rest.put(`${mockBaseUrl}/buckets/:bucket/:key`, async (req, res, ctx) => { const body = await req.json(); const data = { value: JSON.stringify(mockData) }; expect(body).toEqual(data); @@ -162,9 +165,12 @@ describe('Persistent Storage API', () => { const selectedKeyNextHandler = jest.fn(); server.use( - rest.delete(`${mockBaseUrl}/:bucket/:key`, async (_req, res, ctx) => { - return res(ctx.status(204)); - }), + rest.delete( + `${mockBaseUrl}/buckets/:bucket/:key`, + async (_req, res, ctx) => { + return res(ctx.status(204)); + }, + ), ); await new Promise(resolve => { @@ -196,7 +202,7 @@ describe('Persistent Storage API', () => { const selectedKeyNextHandler = jest.fn(); server.use( - rest.put(`${mockBaseUrl}/:bucket/:key`, async (req, res, ctx) => { + rest.put(`${mockBaseUrl}/buckets/:bucket/:key`, async (req, res, ctx) => { const { bucket, key } = req.params; const { value } = await req.json(); @@ -205,7 +211,7 @@ describe('Persistent Storage API', () => { return res(ctx.json({ value })); }), - rest.get(`${mockBaseUrl}/:bucket/:key`, async (req, res, ctx) => { + rest.get(`${mockBaseUrl}/buckets/:bucket/:key`, async (req, res, ctx) => { const { bucket, key } = req.params; expect(bucket).toEqual('default.profile/something'); @@ -253,7 +259,7 @@ describe('Persistent Storage API', () => { }); server.use( - rest.get(`${mockBaseUrl}/:bucket/:key`, async (req, res, ctx) => { + rest.get(`${mockBaseUrl}/buckets/:bucket/:key`, async (req, res, ctx) => { const { bucket, key } = req.params; expect(bucket).toEqual('Test.Mock.Thing'); @@ -290,9 +296,12 @@ describe('Persistent Storage API', () => { const data = { foo: 'bar', baz: [{ foo: 'bar' }] }; server.use( - rest.get(`${mockBaseUrl}/:bucket/:key`, async (_req, res, ctx) => { - return res(ctx.text(JSON.stringify({ value: JSON.stringify(data) }))); - }), + rest.get( + `${mockBaseUrl}/buckets/:bucket/:key`, + async (_req, res, ctx) => { + return res(ctx.text(JSON.stringify({ value: JSON.stringify(data) }))); + }, + ), ); await new Promise(resolve => { diff --git a/packages/core-app-api/src/apis/implementations/StorageApi/PersistentStorage.ts b/packages/core-app-api/src/apis/implementations/StorageApi/PersistentStorage.ts index 4ebf635cd9..38a986863e 100644 --- a/packages/core-app-api/src/apis/implementations/StorageApi/PersistentStorage.ts +++ b/packages/core-app-api/src/apis/implementations/StorageApi/PersistentStorage.ts @@ -182,7 +182,7 @@ export class PersistentStorage implements StorageApi { const baseUrl = await this.discoveryApi.getBaseUrl('user-settings'); const encodedNamespace = encodeURIComponent(this.namespace); const encodedKey = encodeURIComponent(key); - return `${baseUrl}/${encodedNamespace}/${encodedKey}`; + return `${baseUrl}/buckets/${encodedNamespace}/${encodedKey}`; } private async notifyChanges(snapshot: StorageValueSnapshot) { diff --git a/plugins/user-settings-backend/src/service/router.test.ts b/plugins/user-settings-backend/src/service/router.test.ts index ba23ad11c0..21aff9f164 100644 --- a/plugins/user-settings-backend/src/service/router.test.ts +++ b/plugins/user-settings-backend/src/service/router.test.ts @@ -54,7 +54,7 @@ describe('createRouter', () => { jest.resetAllMocks(); }); - describe('GET /', () => { + describe('GET /buckets/', () => { it('returns ok', async () => { const settings = [ { bucket: 'a', key: 'a', value: 'a' }, @@ -67,21 +67,21 @@ describe('createRouter', () => { userSettingsStore.getAll.mockResolvedValue(settings); const responses = await request(app) - .get('/') + .get('/buckets/') .set('Authorization', 'Bearer foo'); expect(responses.status).toEqual(200); expect(responses.body).toEqual(settings); expect(authenticateMock).toHaveBeenCalledWith('foo'); - expect(userSettingsStore.getAll).toBeCalledTimes(1); - expect(userSettingsStore.getAll).toBeCalledWith('tx', { + expect(userSettingsStore.getAll).toHaveBeenCalledTimes(1); + expect(userSettingsStore.getAll).toHaveBeenCalledWith('tx', { userEntityRef: 'user-1', }); }); it('returns an error if the Authorization header is missing', async () => { - const responses = await request(app).get('/'); + const responses = await request(app).get('/buckets/'); expect(responses.status).toEqual(401); expect(userSettingsStore.getAll).not.toHaveBeenCalled(); @@ -93,7 +93,7 @@ describe('createRouter', () => { ); const responses = await request(app) - .get('/') + .get('/buckets/') .set('Authorization', 'Bearer foo'); expect(responses.status).toEqual(401); @@ -101,7 +101,7 @@ describe('createRouter', () => { }); }); - describe('DELETE /', () => { + describe('DELETE /buckets/', () => { it('returns ok', async () => { authenticateMock.mockResolvedValue({ identity: { userEntityRef: 'user-1' }, @@ -110,27 +110,27 @@ describe('createRouter', () => { userSettingsStore.deleteAll.mockResolvedValue(); const responses = await request(app) - .delete('/') + .delete('/buckets/') .set('Authorization', 'Bearer foo'); expect(responses.status).toEqual(204); expect(authenticateMock).toHaveBeenCalledWith('foo'); - expect(userSettingsStore.deleteAll).toBeCalledTimes(1); - expect(userSettingsStore.deleteAll).toBeCalledWith('tx', { + expect(userSettingsStore.deleteAll).toHaveBeenCalledTimes(1); + expect(userSettingsStore.deleteAll).toHaveBeenCalledWith('tx', { userEntityRef: 'user-1', }); }); it('returns an error if the Authorization header is missing', async () => { - const responses = await request(app).delete('/'); + const responses = await request(app).delete('/buckets/'); expect(responses.status).toEqual(401); expect(userSettingsStore.getAll).not.toHaveBeenCalled(); }); }); - describe('GET /:bucket', () => { + describe('GET /buckets/:bucket', () => { it('returns ok', async () => { const settings = [ { bucket: 'my-bucket', key: 'a', value: 'a' }, @@ -143,29 +143,29 @@ describe('createRouter', () => { userSettingsStore.getBucket.mockResolvedValue(settings); const responses = await request(app) - .get('/my-bucket') + .get('/buckets/my-bucket') .set('Authorization', 'Bearer foo'); expect(responses.status).toEqual(200); expect(responses.body).toEqual(settings); expect(authenticateMock).toHaveBeenCalledWith('foo'); - expect(userSettingsStore.getBucket).toBeCalledTimes(1); - expect(userSettingsStore.getBucket).toBeCalledWith('tx', { + expect(userSettingsStore.getBucket).toHaveBeenCalledTimes(1); + expect(userSettingsStore.getBucket).toHaveBeenCalledWith('tx', { userEntityRef: 'user-1', bucket: 'my-bucket', }); }); it('returns an error if the Authorization header is missing', async () => { - const responses = await request(app).get('/my-bucket'); + const responses = await request(app).get('/buckets/my-bucket'); expect(responses.status).toEqual(401); expect(userSettingsStore.getBucket).not.toHaveBeenCalled(); }); }); - describe('DELETE /:bucket', () => { + describe('DELETE /buckets/:bucket', () => { it('returns ok', async () => { authenticateMock.mockResolvedValue({ identity: { userEntityRef: 'user-1' }, @@ -174,28 +174,28 @@ describe('createRouter', () => { userSettingsStore.deleteBucket.mockResolvedValue(); const responses = await request(app) - .delete('/my-bucket') + .delete('/buckets/my-bucket') .set('Authorization', 'Bearer foo'); expect(responses.status).toEqual(204); expect(authenticateMock).toHaveBeenCalledWith('foo'); - expect(userSettingsStore.deleteBucket).toBeCalledTimes(1); - expect(userSettingsStore.deleteBucket).toBeCalledWith('tx', { + expect(userSettingsStore.deleteBucket).toHaveBeenCalledTimes(1); + expect(userSettingsStore.deleteBucket).toHaveBeenCalledWith('tx', { userEntityRef: 'user-1', bucket: 'my-bucket', }); }); it('returns an error if the Authorization header is missing', async () => { - const responses = await request(app).delete('/my-bucket'); + const responses = await request(app).delete('/buckets/my-bucket'); expect(responses.status).toEqual(401); expect(userSettingsStore.deleteBucket).not.toHaveBeenCalled(); }); }); - describe('GET /:bucket/:key', () => { + describe('GET /buckets/:bucket/:key', () => { it('returns ok', async () => { const setting = { bucket: 'my-bucket', key: 'my-key', value: 'a' }; authenticateMock.mockResolvedValue({ @@ -205,15 +205,15 @@ describe('createRouter', () => { userSettingsStore.get.mockResolvedValue(setting); const responses = await request(app) - .get('/my-bucket/my-key') + .get('/buckets/my-bucket/my-key') .set('Authorization', 'Bearer foo'); expect(responses.status).toEqual(200); expect(responses.body).toEqual(setting); expect(authenticateMock).toHaveBeenCalledWith('foo'); - expect(userSettingsStore.get).toBeCalledTimes(1); - expect(userSettingsStore.get).toBeCalledWith('tx', { + expect(userSettingsStore.get).toHaveBeenCalledTimes(1); + expect(userSettingsStore.get).toHaveBeenCalledWith('tx', { userEntityRef: 'user-1', bucket: 'my-bucket', key: 'my-key', @@ -221,14 +221,14 @@ describe('createRouter', () => { }); it('returns an error if the Authorization header is missing', async () => { - const responses = await request(app).get('/my-bucket/my-key'); + const responses = await request(app).get('/buckets/my-bucket/my-key'); expect(responses.status).toEqual(401); expect(userSettingsStore.get).not.toHaveBeenCalled(); }); }); - describe('DELETE /:bucket/:key', () => { + describe('DELETE /buckets/:bucket/:key', () => { it('returns ok', async () => { authenticateMock.mockResolvedValue({ identity: { userEntityRef: 'user-1' }, @@ -237,14 +237,14 @@ describe('createRouter', () => { userSettingsStore.delete.mockResolvedValue(); const responses = await request(app) - .delete('/my-bucket/my-key') + .delete('/buckets/my-bucket/my-key') .set('Authorization', 'Bearer foo'); expect(responses.status).toEqual(204); expect(authenticateMock).toHaveBeenCalledWith('foo'); - expect(userSettingsStore.delete).toBeCalledTimes(1); - expect(userSettingsStore.delete).toBeCalledWith('tx', { + expect(userSettingsStore.delete).toHaveBeenCalledTimes(1); + expect(userSettingsStore.delete).toHaveBeenCalledWith('tx', { userEntityRef: 'user-1', bucket: 'my-bucket', key: 'my-key', @@ -252,14 +252,14 @@ describe('createRouter', () => { }); it('returns an error if the Authorization header is missing', async () => { - const responses = await request(app).delete('/my-bucket/my-key'); + const responses = await request(app).delete('/buckets/my-bucket/my-key'); expect(responses.status).toEqual(401); expect(userSettingsStore.delete).not.toHaveBeenCalled(); }); }); - describe('PUT /:bucket/:key', () => { + describe('PUT /buckets/:bucket/:key', () => { it('returns ok', async () => { const setting = { bucket: 'my-bucket', key: 'my-key', value: 'a' }; authenticateMock.mockResolvedValue({ @@ -270,7 +270,7 @@ describe('createRouter', () => { userSettingsStore.get.mockResolvedValue(setting); const responses = await request(app) - .put('/my-bucket/my-key') + .put('/buckets/my-bucket/my-key') .set('Authorization', 'Bearer foo') .send({ value: 'a' }); @@ -278,15 +278,15 @@ describe('createRouter', () => { expect(responses.body).toEqual(setting); expect(authenticateMock).toHaveBeenCalledWith('foo'); - expect(userSettingsStore.set).toBeCalledTimes(1); + expect(userSettingsStore.set).toHaveBeenCalledTimes(1); expect(userSettingsStore.set).toHaveBeenCalledWith('tx', { userEntityRef: 'user-1', bucket: 'my-bucket', key: 'my-key', value: 'a', }); - expect(userSettingsStore.get).toBeCalledTimes(1); - expect(userSettingsStore.get).toBeCalledWith('tx', { + expect(userSettingsStore.get).toHaveBeenCalledTimes(1); + expect(userSettingsStore.get).toHaveBeenCalledWith('tx', { userEntityRef: 'user-1', bucket: 'my-bucket', key: 'my-key', @@ -299,7 +299,7 @@ describe('createRouter', () => { }); const responses = await request(app) - .put('/my-bucket/my-key') + .put('/buckets/my-bucket/my-key') .set('Authorization', 'Bearer foo') .send({ value: { invalid: 'because not a string' } }); @@ -310,7 +310,7 @@ describe('createRouter', () => { }); it('returns an error if the Authorization header is missing', async () => { - const responses = await request(app).get('/my-bucket/my-key'); + const responses = await request(app).get('/buckets/my-bucket/my-key'); expect(responses.status).toEqual(401); expect(userSettingsStore.get).not.toHaveBeenCalled(); diff --git a/plugins/user-settings-backend/src/service/router.ts b/plugins/user-settings-backend/src/service/router.ts index 0a8c52b156..588759c929 100644 --- a/plugins/user-settings-backend/src/service/router.ts +++ b/plugins/user-settings-backend/src/service/router.ts @@ -63,7 +63,7 @@ export async function createRouter( }; // get all user related settings - router.get('/', async (req, res) => { + router.get('/buckets', async (req, res) => { const userEntityRef = await getUserEntityRef(req); const settings = await userSettingsStore.transaction(tx => @@ -74,7 +74,7 @@ export async function createRouter( }); // remove all user related settings - router.delete('/', async (req, res) => { + router.delete('/buckets', async (req, res) => { const userEntityRef = await getUserEntityRef(req); await userSettingsStore.transaction(tx => @@ -85,7 +85,7 @@ export async function createRouter( }); // get a single bucket - router.get('/:bucket', async (req, res) => { + router.get('/buckets/:bucket', async (req, res) => { const userEntityRef = await getUserEntityRef(req); const { bucket } = req.params; @@ -97,7 +97,7 @@ export async function createRouter( }); // delete a whole bucket - router.delete('/:bucket', async (req, res) => { + router.delete('/buckets/:bucket', async (req, res) => { const userEntityRef = await getUserEntityRef(req); const { bucket } = req.params; @@ -109,7 +109,7 @@ export async function createRouter( }); // get a single value - router.get('/:bucket/:key', async (req, res) => { + router.get('/buckets/:bucket/:key', async (req, res) => { const userEntityRef = await getUserEntityRef(req); const { bucket, key } = req.params; @@ -121,7 +121,7 @@ export async function createRouter( }); // set a single value - router.put('/:bucket/:key', async (req, res) => { + router.put('/buckets/:bucket/:key', async (req, res) => { const userEntityRef = await getUserEntityRef(req); const { bucket, key } = req.params; const { value } = req.body; @@ -144,7 +144,7 @@ export async function createRouter( }); // get a single value - router.delete('/:bucket/:key', async (req, res) => { + router.delete('/buckets/:bucket/:key', async (req, res) => { const userEntityRef = await getUserEntityRef(req); const { bucket, key } = req.params;