diff --git a/lib/ContextParser.ts b/lib/ContextParser.ts index 885d43d..9c86eef 100644 --- a/lib/ContextParser.ts +++ b/lib/ContextParser.ts @@ -239,7 +239,7 @@ Tried mapping ${key} to ${JSON.stringify(keyValue)}`, ERROR_CODES.INVALID_KEYWOR } /** - * Normalize and apply context-levevl @protected terms onto each term separately. + * Normalize and apply context-level @protected terms onto each term separately. * @param {IJsonLdContextNormalizedRaw} context A context. * @param {number} processingMode The processing mode. */ @@ -769,6 +769,18 @@ must be one of ${Util.CONTAINERS.join(', ')}`, ERROR_CODES.INVALID_CONTAINER_MAP } // Merge different parts of the final context in order + // FIXME: We need to have logic here to prevent overriding based on the `@protected` keyword. + // FIXME: Check the merge is happening in the right order + // Handle terms (before protection checks) + + // NOTE: There may still be *some* issues here if a different context is required to fully expand a protected + // term (though I'm not actually sure this is allowed?) + const contextWrapped = new JsonLdContextNormalized(context); + this.idifyReverseTerms(context); + this.expandPrefixedTerms(contextWrapped, this.expandContentTypeToBase); + + this.applyScopedProtected(context, { processingMode }); + // FIXME: See if we need to apply scoping on anything else newContext = { ...newContext, ...(typeof parentContext === 'object' ? parentContext : {}), @@ -799,6 +811,7 @@ must be one of ${Util.CONTAINERS.join(', ')}`, ERROR_CODES.INVALID_CONTAINER_MAP // In JSON-LD 1.1, check if we are not redefining any protected keywords if (!ignoreProtection && parentContext && processingMode >= 1.1) { + // FIXME: See why version conflicts aren't being complained about here this.validateKeywordRedefinitions(parentContext, newContext, defaultExpandOptions); } diff --git a/package.json b/package.json index 0dc08c0..c5510f7 100644 --- a/package.json +++ b/package.json @@ -76,7 +76,7 @@ "test": "jest ${1}", "test-watch": "jest ${1} --watch", "coveralls": "jest --coverage && cat ./coverage/lcov.info | coveralls", - "lint": "tslint index.ts lib/**/*.ts test/**/*.ts --exclude '**/*.d.ts'", + "lint": "tslint index.ts lib/**/*.ts test/**/*.ts test/*.ts --exclude '**/*.d.ts'", "build": "tsc", "build-watch": "tsc --watch", "validate": "npm ls", diff --git a/test/ContextParser-test.ts b/test/ContextParser-test.ts index 4b05144..d497d02 100644 --- a/test/ContextParser-test.ts +++ b/test/ContextParser-test.ts @@ -2132,6 +2132,111 @@ Tried mapping @id to {}`, ERROR_CODES.KEYWORD_REDEFINITION)); })); }); + // There i + it('should parse 2 contexts where one is protected', () => { + return expect(parser.parse([ + { + // NOTE: This gets elevated to 1.1; when the contexts get merged. + // We should add a test here which uses a 1.0 specific feature. + "@version": 1.0, + "ex":"https://example.org/ns/" + }, + { + "@version": 1.1, + "@protected": true, + "VerifiableCredential": { + "@id": "https://www.w3.org/2018/credentials#VerifiableCredential", + } + } + ])).resolves.toEqual(new JsonLdContextNormalized({ + "@version": 1.1, + VerifiableCredential: { + "@id": "https://www.w3.org/2018/credentials#VerifiableCredential", + "@protected": true, + }, + ex: "https://example.org/ns/" + })); + }); + + const contexts = [ + { + "@version": 1.1, + "@protected": true, + "VerifiableCredential": { + "@id": "https://www.w3.org/2018/credentials#VerifiableCredential", + } + }, + { + "ex":"https://example.org/ns/", + "@version": 1.1, + "@protected": false, + } + ]; + + const result = new JsonLdContextNormalized({ + "@version": 1.1, + // FIXME: See why there is an explicit false in the normalized context. I would think that this could + // just be deleted + "@protected": false, + VerifiableCredential: { + "@id": "https://www.w3.org/2018/credentials#VerifiableCredential", + "@protected": true, + }, + ex: "https://example.org/ns/" + }); + + it('should parse 2 contexts where one is protected and one globally has protected false', () => { + return expect(parser.parse(contexts)).resolves.toEqual(result); + }); + + it('should parse 2 contexts where one is protected and one globally has protected false [reverse order]', () => { + return expect(parser.parse([contexts[1], contexts[0]])).resolves.toEqual(result); + }); + + it('protected context should override the unprotected context', () => { + return expect(parser.parse([ + { + // NOTE: This gets elevated to 1.1; when the contexts get merged. + // We should add a test here which uses a 1.0 specific feature. + "@version": 1.0, + "VerifiableCredential":"https://example.org/ns/" + }, + { + "@version": 1.1, + "@protected": true, + "VerifiableCredential": { + "@id": "https://www.w3.org/2018/credentials#VerifiableCredential", + } + } + ])).resolves.toEqual(new JsonLdContextNormalized({ + "@version": 1.1, + VerifiableCredential: { + "@id": "https://www.w3.org/2018/credentials#VerifiableCredential", + "@protected": true, + } + })); + }); + + it('should parse 2 contexts where one is protected', () => { + return expect(parser.parse([ + {"ex":"https://example.org/ns/"}, + { + "@version": 1.1, + "@protected": true, + "VerifiableCredential": { + "@id": "https://www.w3.org/2018/credentials#VerifiableCredential", + } + } + ])).resolves.toEqual(new JsonLdContextNormalized({ + "@version": 1.1, + VerifiableCredential: { + "@id": "https://www.w3.org/2018/credentials#VerifiableCredential", + "@protected": true, + }, + ex: "https://example.org/ns/" + })); + }); + it('should parse a single keyword alias', () => { return expect(parser.parse({ id: { @@ -2214,6 +2319,60 @@ Tried mapping @id to {}`, ERROR_CODES.KEYWORD_REDEFINITION)); ERROR_CODES.PROTECTED_TERM_REDEFINITION)); }); + it('should error on a protected term with override when the overriding version is 1.0', () => { + return expect(parser.parse([ + { + name: { + '@id': 'http://xmlns.com/foaf/0.1/name', + '@protected': true, + }, + }, + { + "@version": 1.0, + name: 'http://schema.org/name', + }, + ])).rejects.toThrow(new ErrorCoded( + 'Attempted to override the protected keyword name from ' + + '"http://xmlns.com/foaf/0.1/name" to "http://schema.org/name"', + ERROR_CODES.PROTECTED_TERM_REDEFINITION)); + }); + + it('should error on an outer scope protected term with override of another protected term', () => { + return expect(parser.parse([ + { + "VerifiableCredential":"https://example.org/ns/", + "@protected": true + }, + { + "@version": 1.1, + "@protected": true, + "VerifiableCredential": { + "@id": "https://www.w3.org/2018/credentials#VerifiableCredential", + } + } + ], { processingMode: 1.1 })).rejects.toThrow(new ErrorCoded( + 'Attempted to override the protected keyword VerifiableCredential from ' + + '"https://example.org/ns/" to "https://www.w3.org/2018/credentials#VerifiableCredential"', + ERROR_CODES.PROTECTED_TERM_REDEFINITION)); + }); + + it('should error on an outer scope protected term with override', () => { + return expect(parser.parse([ + { + '@protected': true, + name: { + '@id': 'http://xmlns.com/foaf/0.1/name', + }, + }, + { + name: 'http://schema.org/name', + }, + ], { processingMode: 1.1 })).rejects.toThrow(new ErrorCoded( + 'Attempted to override the protected keyword name from ' + + '"http://xmlns.com/foaf/0.1/name" to "http://schema.org/name"', + ERROR_CODES.PROTECTED_TERM_REDEFINITION)); + }); + it('should not error on a protected term with override if ignoreProtection is true', () => { return expect(parser.parse([ {