diff --git a/lib/api/filters.js b/lib/api/filters.js index ed289ca3..36d9b86c 100644 --- a/lib/api/filters.js +++ b/lib/api/filters.js @@ -10,7 +10,7 @@ const { nextPageCursorSchema, previousPageCursorSchema, sessSchema, sessIPSchema const { publish, FILTER_DELETED, FILTER_CREATED, FORWARD_ADDED } = require('../events'); const { successRes, totalRes, previousCursorRes, nextCursorRes } = require('../schemas/response/general-schemas'); const { GetAllFiltersResult, GetFiltersResult } = require('../schemas/response/filters-schemas'); -const { FilterQuery, FilterAction, FilterActionUpdate } = require('../schemas/request/filters-schemas'); +const { FilterQuery, FilterAction } = require('../schemas/request/filters-schemas'); const { userId, filterId } = require('../schemas/request/general-schemas'); const { mongopagingFindWrapper } = require('../mongopaging-find-wrapper'); @@ -995,7 +995,7 @@ module.exports = (db, server, userHandler, settingsHandler) => { name: Joi.string().trim().max(255).empty('').description('Name of the Filter'), query: FilterQuery, - action: FilterActionUpdate, + action: FilterAction, disabled: booleanSchema.description('If true then this filter is ignored'), diff --git a/lib/schemas/request/filters-schemas.js b/lib/schemas/request/filters-schemas.js index 0997c9fb..644d2832 100644 --- a/lib/schemas/request/filters-schemas.js +++ b/lib/schemas/request/filters-schemas.js @@ -4,10 +4,10 @@ const Joi = require('joi'); const { booleanSchema } = require('../../schemas'); const FilterAction = Joi.object({ - seen: booleanSchema.description('If true then mark matching messages as Seen'), - flag: booleanSchema.description('If true then mark matching messages as Flagged'), - delete: booleanSchema.description('If true then do not store matching messages'), - spam: booleanSchema.description('If true then store matching messages to Junk Mail folder'), + seen: booleanSchema.allow(null).description('If true then mark matching messages as Seen (null clears action)'), + flag: booleanSchema.allow(null).description('If true then mark matching messages as Flagged (null clears action)'), + delete: booleanSchema.allow(null).description('If true then do not store matching messages (null clears action)'), + spam: booleanSchema.allow(null).description('If true then store matching messages to Junk Mail folder (null clears action)'), mailbox: Joi.string().hex().lowercase().length(24).empty('').description('Mailbox ID to store matching messages to'), targets: Joi.array() .items( @@ -51,8 +51,4 @@ const FilterQuery = Joi.object({ .description('Rules that a message must match') .$_setFlag('objectName', 'Query'); -const FilterActionUpdate = FilterAction.keys({ - spam: booleanSchema.allow(null).description('If true then store matching messages to Junk Mail folder (null clears action)') -}); - -module.exports = { FilterAction, FilterQuery, FilterActionUpdate }; +module.exports = { FilterAction, FilterQuery }; diff --git a/test/api/filters-test.js b/test/api/filters-test.js index 2102bf22..1a1c0c73 100644 --- a/test/api/filters-test.js +++ b/test/api/filters-test.js @@ -251,6 +251,71 @@ describe('API Filters', function () { }); }); + describe('Filter nullable boolean actions', function () { + let nullableUpdateFilter; + + it('should POST /users/{user}/filters expect success / ignore null seen, flag and delete actions', async () => { + const response = await server + .post(`/users/${user}/filters`) + .send({ + name: 'nullable boolean actions create', + query: { + from: 'nullable-create' + }, + action: { + seen: null, + flag: null, + delete: null + } + }) + .expect(200); + expect(response.body.success).to.be.true; + + const filterDataResponse = await server.get(`/users/${user}/filters/${response.body.id}`).expect(200); + expect(filterDataResponse.body.success).to.be.true; + expect(filterDataResponse.body.action).to.not.have.property('seen'); + expect(filterDataResponse.body.action).to.not.have.property('flag'); + expect(filterDataResponse.body.action).to.not.have.property('delete'); + }); + + it('should PUT /users/{user}/filters/{filter} expect success / clear seen, flag and delete actions with null values', async () => { + const createResponse = await server + .post(`/users/${user}/filters`) + .send({ + name: 'nullable boolean actions update', + query: { + from: 'nullable-update' + }, + action: { + seen: true, + flag: true, + delete: true + } + }) + .expect(200); + expect(createResponse.body.success).to.be.true; + nullableUpdateFilter = createResponse.body.id; + + const response = await server + .put(`/users/${user}/filters/${nullableUpdateFilter}`) + .send({ + action: { + seen: null, + flag: null, + delete: null + } + }) + .expect(200); + expect(response.body.success).to.be.true; + + const filterDataResponse = await server.get(`/users/${user}/filters/${nullableUpdateFilter}`).expect(200); + expect(filterDataResponse.body.success).to.be.true; + expect(filterDataResponse.body.action).to.not.have.property('seen'); + expect(filterDataResponse.body.action).to.not.have.property('flag'); + expect(filterDataResponse.body.action).to.not.have.property('delete'); + }); + }); + describe('Filter metaData', function () { let metaDataFilter;