diff options
Diffstat (limited to 'test/test-profile-conditions-util.js')
| -rw-r--r-- | test/test-profile-conditions-util.js | 843 | 
1 files changed, 843 insertions, 0 deletions
| diff --git a/test/test-profile-conditions-util.js b/test/test-profile-conditions-util.js new file mode 100644 index 00000000..ebc72be7 --- /dev/null +++ b/test/test-profile-conditions-util.js @@ -0,0 +1,843 @@ +/* + * Copyright (C) 2020-2021  Yomichan Authors + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program.  If not, see <https://www.gnu.org/licenses/>. + */ + +const assert = require('assert'); +const {testMain} = require('../dev/util'); +const {VM} = require('../dev/vm'); + + +const vm = new VM({}); +vm.execute([ +    'js/core.js', +    'js/general/cache-map.js', +    'js/data/json-schema.js', +    'js/background/profile-conditions-util.js' +]); +const [JsonSchemaValidator, ProfileConditionsUtil] = vm.get(['JsonSchemaValidator', 'ProfileConditionsUtil']); + + +function schemaValidate(value, schema) { +    return new JsonSchemaValidator().isValid(value, schema); +} + + +function testNormalizeContext() { +    const data = [ +        // Empty +        { +            context: {}, +            expected: {} +        }, + +        // Domain normalization +        { +            context: {url: ''}, +            expected: {url: ''} +        }, +        { +            context: {url: 'http://example.com/'}, +            expected: {url: 'http://example.com/', domain: 'example.com'} +        }, +        { +            context: {url: 'http://example.com:1234/'}, +            expected: {url: 'http://example.com:1234/', domain: 'example.com'} +        }, +        { +            context: {url: 'http://user@example.com:1234/'}, +            expected: {url: 'http://user@example.com:1234/', domain: 'example.com'} +        } +    ]; + +    for (const {context, expected} of data) { +        const profileConditionsUtil = new ProfileConditionsUtil(); +        const actual = profileConditionsUtil.normalizeContext(context); +        vm.assert.deepStrictEqual(actual, expected); +    } +} + +function testSchemas() { +    const data = [ +        // Empty +        { +            conditionGroups: [], +            expectedSchema: {}, +            inputs: [ +                {expected: true, context: {url: 'http://example.com/'}} +            ] +        }, +        { +            conditionGroups: [ +                {conditions: []} +            ], +            expectedSchema: {}, +            inputs: [ +                {expected: true, context: {url: 'http://example.com/'}} +            ] +        }, +        { +            conditionGroups: [ +                {conditions: []}, +                {conditions: []} +            ], +            expectedSchema: {}, +            inputs: [ +                {expected: true, context: {url: 'http://example.com/'}} +            ] +        }, + +        // popupLevel tests +        { +            conditionGroups: [ +                { +                    conditions: [ +                        { +                            type: 'popupLevel', +                            operator: 'equal', +                            value: '0' +                        } +                    ] +                } +            ], +            expectedSchema: { +                properties: { +                    depth: {const: 0} +                }, +                required: ['depth'] +            }, +            inputs: [ +                {expected: true,  context: {depth: 0, url: 'http://example.com/'}}, +                {expected: false, context: {depth: 1, url: 'http://example.com/'}}, +                {expected: false, context: {depth: -1, url: 'http://example.com/'}} +            ] +        }, +        { +            conditionGroups: [ +                { +                    conditions: [ +                        { +                            type: 'popupLevel', +                            operator: 'notEqual', +                            value: '0' +                        } +                    ] +                } +            ], +            expectedSchema: { +                not: [ +                    { +                        properties: { +                            depth: {const: 0} +                        }, +                        required: ['depth'] +                    } +                ] +            }, +            inputs: [ +                {expected: false, context: {depth: 0, url: 'http://example.com/'}}, +                {expected: true,  context: {depth: 1, url: 'http://example.com/'}}, +                {expected: true,  context: {depth: -1, url: 'http://example.com/'}} +            ] +        }, +        { +            conditionGroups: [ +                { +                    conditions: [ +                        { +                            type: 'popupLevel', +                            operator: 'lessThan', +                            value: '0' +                        } +                    ] +                } +            ], +            expectedSchema: { +                properties: { +                    depth: { +                        type: 'number', +                        exclusiveMaximum: 0 +                    } +                }, +                required: ['depth'] +            }, +            inputs: [ +                {expected: false, context: {depth: 0, url: 'http://example.com/'}}, +                {expected: false, context: {depth: 1, url: 'http://example.com/'}}, +                {expected: true,  context: {depth: -1, url: 'http://example.com/'}} +            ] +        }, +        { +            conditionGroups: [ +                { +                    conditions: [ +                        { +                            type: 'popupLevel', +                            operator: 'greaterThan', +                            value: '0' +                        } +                    ] +                } +            ], +            expectedSchema: { +                properties: { +                    depth: { +                        type: 'number', +                        exclusiveMinimum: 0 +                    } +                }, +                required: ['depth'] +            }, +            inputs: [ +                {expected: false, context: {depth: 0, url: 'http://example.com/'}}, +                {expected: true,  context: {depth: 1, url: 'http://example.com/'}}, +                {expected: false, context: {depth: -1, url: 'http://example.com/'}} +            ] +        }, +        { +            conditionGroups: [ +                { +                    conditions: [ +                        { +                            type: 'popupLevel', +                            operator: 'lessThanOrEqual', +                            value: '0' +                        } +                    ] +                } +            ], +            expectedSchema: { +                properties: { +                    depth: { +                        type: 'number', +                        maximum: 0 +                    } +                }, +                required: ['depth'] +            }, +            inputs: [ +                {expected: true,  context: {depth: 0, url: 'http://example.com/'}}, +                {expected: false, context: {depth: 1, url: 'http://example.com/'}}, +                {expected: true,  context: {depth: -1, url: 'http://example.com/'}} +            ] +        }, +        { +            conditionGroups: [ +                { +                    conditions: [ +                        { +                            type: 'popupLevel', +                            operator: 'greaterThanOrEqual', +                            value: '0' +                        } +                    ] +                } +            ], +            expectedSchema: { +                properties: { +                    depth: { +                        type: 'number', +                        minimum: 0 +                    } +                }, +                required: ['depth'] +            }, +            inputs: [ +                {expected: true,  context: {depth: 0, url: 'http://example.com/'}}, +                {expected: true,  context: {depth: 1, url: 'http://example.com/'}}, +                {expected: false, context: {depth: -1, url: 'http://example.com/'}} +            ] +        }, + +        // url tests +        { +            conditionGroups: [ +                { +                    conditions: [ +                        { +                            type: 'url', +                            operator: 'matchDomain', +                            value: 'example.com' +                        } +                    ] +                } +            ], +            expectedSchema: { +                properties: { +                    domain: { +                        oneOf: [ +                            {const: 'example.com'} +                        ] +                    } +                }, +                required: ['domain'] +            }, +            inputs: [ +                {expected: true,  context: {depth: 0, url: 'http://example.com/'}}, +                {expected: false, context: {depth: 0, url: 'http://example1.com/'}}, +                {expected: false, context: {depth: 0, url: 'http://example2.com/'}}, +                {expected: true,  context: {depth: 0, url: 'http://example.com:1234/'}}, +                {expected: true,  context: {depth: 0, url: 'http://user@example.com:1234/'}} +            ] +        }, +        { +            conditionGroups: [ +                { +                    conditions: [ +                        { +                            type: 'url', +                            operator: 'matchDomain', +                            value: 'example.com, example1.com, example2.com' +                        } +                    ] +                } +            ], +            expectedSchema: { +                properties: { +                    domain: { +                        oneOf: [ +                            {const: 'example.com'}, +                            {const: 'example1.com'}, +                            {const: 'example2.com'} +                        ] +                    } +                }, +                required: ['domain'] +            }, +            inputs: [ +                {expected: true,  context: {depth: 0, url: 'http://example.com/'}}, +                {expected: true,  context: {depth: 0, url: 'http://example1.com/'}}, +                {expected: true,  context: {depth: 0, url: 'http://example2.com/'}}, +                {expected: false, context: {depth: 0, url: 'http://example3.com/'}}, +                {expected: true,  context: {depth: 0, url: 'http://example.com:1234/'}}, +                {expected: true,  context: {depth: 0, url: 'http://user@example.com:1234/'}} +            ] +        }, +        { +            conditionGroups: [ +                { +                    conditions: [ +                        { +                            type: 'url', +                            operator: 'matchRegExp', +                            value: '^http://example\\d?\\.com/[\\w\\W]*$' +                        } +                    ] +                } +            ], +            expectedSchema: { +                properties: { +                    url: { +                        type: 'string', +                        pattern: '^http://example\\d?\\.com/[\\w\\W]*$', +                        patternFlags: 'i' +                    } +                }, +                required: ['url'] +            }, +            inputs: [ +                {expected: true,  context: {depth: 0, url: 'http://example.com/'}}, +                {expected: true,  context: {depth: 0, url: 'http://example1.com/'}}, +                {expected: true,  context: {depth: 0, url: 'http://example2.com/'}}, +                {expected: true,  context: {depth: 0, url: 'http://example3.com/'}}, +                {expected: true,  context: {depth: 0, url: 'http://example.com/example'}}, +                {expected: false, context: {depth: 0, url: 'http://example.com:1234/'}}, +                {expected: false, context: {depth: 0, url: 'http://user@example.com:1234/'}}, +                {expected: false, context: {depth: 0, url: 'http://example-1.com/'}} +            ] +        }, + +        // modifierKeys tests +        { +            conditionGroups: [ +                { +                    conditions: [ +                        { +                            type: 'modifierKeys', +                            operator: 'are', +                            value: '' +                        } +                    ] +                } +            ], +            expectedSchema: { +                properties: { +                    modifierKeys: { +                        type: 'array', +                        maxItems: 0, +                        minItems: 0 +                    } +                }, +                required: ['modifierKeys'] +            }, +            inputs: [ +                {expected: true,  context: {depth: 0, url: 'http://example.com/', modifierKeys: []}}, +                {expected: false, context: {depth: 0, url: 'http://example.com/', modifierKeys: ['Alt']}}, +                {expected: false, context: {depth: 0, url: 'http://example.com/', modifierKeys: ['Alt', 'Shift']}}, +                {expected: false, context: {depth: 0, url: 'http://example.com/', modifierKeys: ['Alt', 'Shift', 'Ctrl']}} +            ] +        }, +        { +            conditionGroups: [ +                { +                    conditions: [ +                        { +                            type: 'modifierKeys', +                            operator: 'are', +                            value: 'Alt, Shift' +                        } +                    ] +                } +            ], +            expectedSchema: { +                properties: { +                    modifierKeys: { +                        type: 'array', +                        maxItems: 2, +                        minItems: 2, +                        allOf: [ +                            {contains: {const: 'Alt'}}, +                            {contains: {const: 'Shift'}} +                        ] +                    } +                }, +                required: ['modifierKeys'] +            }, +            inputs: [ +                {expected: false, context: {depth: 0, url: 'http://example.com/', modifierKeys: []}}, +                {expected: false, context: {depth: 0, url: 'http://example.com/', modifierKeys: ['Alt']}}, +                {expected: true,  context: {depth: 0, url: 'http://example.com/', modifierKeys: ['Alt', 'Shift']}}, +                {expected: false, context: {depth: 0, url: 'http://example.com/', modifierKeys: ['Alt', 'Shift', 'Ctrl']}} +            ] +        }, +        { +            conditionGroups: [ +                { +                    conditions: [ +                        { +                            type: 'modifierKeys', +                            operator: 'areNot', +                            value: '' +                        } +                    ] +                } +            ], +            expectedSchema: { +                not: [ +                    { +                        properties: { +                            modifierKeys: { +                                type: 'array', +                                maxItems: 0, +                                minItems: 0 +                            } +                        }, +                        required: ['modifierKeys'] +                    } +                ] +            }, +            inputs: [ +                {expected: false, context: {depth: 0, url: 'http://example.com/', modifierKeys: []}}, +                {expected: true,  context: {depth: 0, url: 'http://example.com/', modifierKeys: ['Alt']}}, +                {expected: true,  context: {depth: 0, url: 'http://example.com/', modifierKeys: ['Alt', 'Shift']}}, +                {expected: true,  context: {depth: 0, url: 'http://example.com/', modifierKeys: ['Alt', 'Shift', 'Ctrl']}} +            ] +        }, +        { +            conditionGroups: [ +                { +                    conditions: [ +                        { +                            type: 'modifierKeys', +                            operator: 'areNot', +                            value: 'Alt, Shift' +                        } +                    ] +                } +            ], +            expectedSchema: { +                not: [ +                    { +                        properties: { +                            modifierKeys: { +                                type: 'array', +                                maxItems: 2, +                                minItems: 2, +                                allOf: [ +                                    {contains: {const: 'Alt'}}, +                                    {contains: {const: 'Shift'}} +                                ] +                            } +                        }, +                        required: ['modifierKeys'] +                    } +                ] +            }, +            inputs: [ +                {expected: true,  context: {depth: 0, url: 'http://example.com/', modifierKeys: []}}, +                {expected: true,  context: {depth: 0, url: 'http://example.com/', modifierKeys: ['Alt']}}, +                {expected: false, context: {depth: 0, url: 'http://example.com/', modifierKeys: ['Alt', 'Shift']}}, +                {expected: true,  context: {depth: 0, url: 'http://example.com/', modifierKeys: ['Alt', 'Shift', 'Ctrl']}} +            ] +        }, +        { +            conditionGroups: [ +                { +                    conditions: [ +                        { +                            type: 'modifierKeys', +                            operator: 'include', +                            value: '' +                        } +                    ] +                } +            ], +            expectedSchema: { +                properties: { +                    modifierKeys: { +                        type: 'array', +                        minItems: 0 +                    } +                }, +                required: ['modifierKeys'] +            }, +            inputs: [ +                {expected: true,  context: {depth: 0, url: 'http://example.com/', modifierKeys: []}}, +                {expected: true,  context: {depth: 0, url: 'http://example.com/', modifierKeys: ['Alt']}}, +                {expected: true,  context: {depth: 0, url: 'http://example.com/', modifierKeys: ['Alt', 'Shift']}}, +                {expected: true,  context: {depth: 0, url: 'http://example.com/', modifierKeys: ['Alt', 'Shift', 'Ctrl']}} +            ] +        }, +        { +            conditionGroups: [ +                { +                    conditions: [ +                        { +                            type: 'modifierKeys', +                            operator: 'include', +                            value: 'Alt, Shift' +                        } +                    ] +                } +            ], +            expectedSchema: { +                properties: { +                    modifierKeys: { +                        type: 'array', +                        minItems: 2, +                        allOf: [ +                            {contains: {const: 'Alt'}}, +                            {contains: {const: 'Shift'}} +                        ] +                    } +                }, +                required: ['modifierKeys'] +            }, +            inputs: [ +                {expected: false, context: {depth: 0, url: 'http://example.com/', modifierKeys: []}}, +                {expected: false, context: {depth: 0, url: 'http://example.com/', modifierKeys: ['Alt']}}, +                {expected: true,  context: {depth: 0, url: 'http://example.com/', modifierKeys: ['Alt', 'Shift']}}, +                {expected: true,  context: {depth: 0, url: 'http://example.com/', modifierKeys: ['Alt', 'Shift', 'Ctrl']}} +            ] +        }, +        { +            conditionGroups: [ +                { +                    conditions: [ +                        { +                            type: 'modifierKeys', +                            operator: 'notInclude', +                            value: '' +                        } +                    ] +                } +            ], +            expectedSchema: { +                properties: { +                    modifierKeys: { +                        type: 'array' +                    } +                }, +                required: ['modifierKeys'] +            }, +            inputs: [ +                {expected: true,  context: {depth: 0, url: 'http://example.com/', modifierKeys: []}}, +                {expected: true,  context: {depth: 0, url: 'http://example.com/', modifierKeys: ['Alt']}}, +                {expected: true,  context: {depth: 0, url: 'http://example.com/', modifierKeys: ['Alt', 'Shift']}}, +                {expected: true,  context: {depth: 0, url: 'http://example.com/', modifierKeys: ['Alt', 'Shift', 'Ctrl']}} +            ] +        }, +        { +            conditionGroups: [ +                { +                    conditions: [ +                        { +                            type: 'modifierKeys', +                            operator: 'notInclude', +                            value: 'Alt, Shift' +                        } +                    ] +                } +            ], +            expectedSchema: { +                properties: { +                    modifierKeys: { +                        type: 'array', +                        not: [ +                            {contains: {const: 'Alt'}}, +                            {contains: {const: 'Shift'}} +                        ] +                    } +                }, +                required: ['modifierKeys'] +            }, +            inputs: [ +                {expected: true,  context: {depth: 0, url: 'http://example.com/', modifierKeys: []}}, +                {expected: false, context: {depth: 0, url: 'http://example.com/', modifierKeys: ['Alt']}}, +                {expected: false, context: {depth: 0, url: 'http://example.com/', modifierKeys: ['Alt', 'Shift']}}, +                {expected: false, context: {depth: 0, url: 'http://example.com/', modifierKeys: ['Alt', 'Shift', 'Ctrl']}} +            ] +        }, + +        // Multiple conditions tests +        { +            conditionGroups: [ +                { +                    conditions: [ +                        { +                            type: 'popupLevel', +                            operator: 'greaterThan', +                            value: '0' +                        }, +                        { +                            type: 'popupLevel', +                            operator: 'lessThan', +                            value: '3' +                        } +                    ] +                } +            ], +            expectedSchema: { +                allOf: [ +                    { +                        properties: { +                            depth: { +                                type: 'number', +                                exclusiveMinimum: 0 +                            } +                        }, +                        required: ['depth'] +                    }, +                    { +                        properties: { +                            depth: { +                                type: 'number', +                                exclusiveMaximum: 3 +                            } +                        }, +                        required: ['depth'] +                    } +                ] +            }, +            inputs: [ +                {expected: false, context: {depth: -2, url: 'http://example.com/'}}, +                {expected: false, context: {depth: -1, url: 'http://example.com/'}}, +                {expected: false, context: {depth: 0, url: 'http://example.com/'}}, +                {expected: true,  context: {depth: 1, url: 'http://example.com/'}}, +                {expected: true,  context: {depth: 2, url: 'http://example.com/'}}, +                {expected: false, context: {depth: 3, url: 'http://example.com/'}} +            ] +        }, +        { +            conditionGroups: [ +                { +                    conditions: [ +                        { +                            type: 'popupLevel', +                            operator: 'greaterThan', +                            value: '0' +                        }, +                        { +                            type: 'popupLevel', +                            operator: 'lessThan', +                            value: '3' +                        } +                    ] +                }, +                { +                    conditions: [ +                        { +                            type: 'popupLevel', +                            operator: 'equal', +                            value: '0' +                        } +                    ] +                } +            ], +            expectedSchema: { +                anyOf: [ +                    { +                        allOf: [ +                            { +                                properties: { +                                    depth: { +                                        type: 'number', +                                        exclusiveMinimum: 0 +                                    } +                                }, +                                required: ['depth'] +                            }, +                            { +                                properties: { +                                    depth: { +                                        type: 'number', +                                        exclusiveMaximum: 3 +                                    } +                                }, +                                required: ['depth'] +                            } +                        ] +                    }, +                    { +                        properties: { +                            depth: {const: 0} +                        }, +                        required: ['depth'] +                    } +                ] +            }, +            inputs: [ +                {expected: false, context: {depth: -2, url: 'http://example.com/'}}, +                {expected: false, context: {depth: -1, url: 'http://example.com/'}}, +                {expected: true,  context: {depth: 0, url: 'http://example.com/'}}, +                {expected: true,  context: {depth: 1, url: 'http://example.com/'}}, +                {expected: true,  context: {depth: 2, url: 'http://example.com/'}}, +                {expected: false, context: {depth: 3, url: 'http://example.com/'}} +            ] +        }, +        { +            conditionGroups: [ +                { +                    conditions: [ +                        { +                            type: 'popupLevel', +                            operator: 'greaterThan', +                            value: '0' +                        }, +                        { +                            type: 'popupLevel', +                            operator: 'lessThan', +                            value: '3' +                        } +                    ] +                }, +                { +                    conditions: [ +                        { +                            type: 'popupLevel', +                            operator: 'lessThanOrEqual', +                            value: '0' +                        }, +                        { +                            type: 'popupLevel', +                            operator: 'greaterThanOrEqual', +                            value: '-1' +                        } +                    ] +                } +            ], +            expectedSchema: { +                anyOf: [ +                    { +                        allOf: [ +                            { +                                properties: { +                                    depth: { +                                        type: 'number', +                                        exclusiveMinimum: 0 +                                    } +                                }, +                                required: ['depth'] +                            }, +                            { +                                properties: { +                                    depth: { +                                        type: 'number', +                                        exclusiveMaximum: 3 +                                    } +                                }, +                                required: ['depth'] +                            } +                        ] +                    }, +                    { +                        allOf: [ +                            { +                                properties: { +                                    depth: { +                                        type: 'number', +                                        maximum: 0 +                                    } +                                }, +                                required: ['depth'] +                            }, +                            { +                                properties: { +                                    depth: { +                                        type: 'number', +                                        minimum: -1 +                                    } +                                }, +                                required: ['depth'] +                            } +                        ] +                    } +                ] +            }, +            inputs: [ +                {expected: false, context: {depth: -2, url: 'http://example.com/'}}, +                {expected: true,  context: {depth: -1, url: 'http://example.com/'}}, +                {expected: true,  context: {depth: 0, url: 'http://example.com/'}}, +                {expected: true,  context: {depth: 1, url: 'http://example.com/'}}, +                {expected: true,  context: {depth: 2, url: 'http://example.com/'}}, +                {expected: false, context: {depth: 3, url: 'http://example.com/'}} +            ] +        } +    ]; + +    for (const {conditionGroups, expectedSchema, inputs} of data) { +        const profileConditionsUtil = new ProfileConditionsUtil(); +        const schema = profileConditionsUtil.createSchema(conditionGroups); +        if (typeof expectedSchema !== 'undefined') { +            vm.assert.deepStrictEqual(schema, expectedSchema); +        } +        if (Array.isArray(inputs)) { +            for (const {expected, context} of inputs) { +                const normalizedContext = profileConditionsUtil.normalizeContext(context); +                const actual = schemaValidate(normalizedContext, schema); +                assert.strictEqual(actual, expected); +            } +        } +    } +} + + +function main() { +    testNormalizeContext(); +    testSchemas(); +} + + +if (require.main === module) { testMain(main); } |