UNPKG

@inrupt/solid-client

Version:
1,580 lines (1,460 loc) • 60.3 kB
/** * Copyright 2020 Inrupt Inc. * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal in * the Software without restriction, including without limitation the rights to use, * copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the * Software, and to permit persons to whom the Software is furnished to do so, * subject to the following conditions: * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, * INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A * PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ import { describe, it, expect } from "@jest/globals"; import { NamedNode } from "rdf-js"; import { DataFactory } from "n3"; import { asIri, createThing, getThing, getThingAll, isThing, setThing, } from "../thing/thing"; import { addAgent, addNoneOfRuleUrl, addGroup, addAnyOfRuleUrl, addAllOfRuleUrl, createRule, getAgentAll, getNoneOfRuleUrlAll, getGroupAll, getAnyOfRuleUrlAll, getAllOfRuleUrlAll, removeNoneOfRuleUrl, removeAnyOfRuleUrl, removeAllOfRuleUrl, getRule, hasAuthenticated, hasPublic, removeAgent, removeGroup, Rule, setAgent, setAuthenticated, setNoneOfRuleUrl, setGroup, setAnyOfRuleUrl, setPublic, setAllOfRuleUrl, getRuleAll, setRule, hasCreator, setCreator, ruleAsMarkdown, removeRule, getClientAll, setClient, addClient, removeClient, hasAnyClient, setAnyClient, removePublic, removeAuthenticated, removeCreator, removeAnyClient, getResourceRule, getResourceRuleAll, removeResourceRule, setResourceRule, createResourceRuleFor, } from "./rule"; import { Policy } from "./policy"; import { createSolidDataset } from "../resource/solidDataset"; import { setUrl } from "../thing/set"; import { Thing, ThingPersisted, Url, UrlString } from "../interfaces"; import { acp, rdf } from "../constants"; import { getIri, getIriAll, getSourceUrl, mockSolidDatasetFrom, } from "../index"; import { addMockAcrTo, mockAcrFor } from "./mock"; import { internal_getAcr } from "./control.internal"; // Vocabulary terms const ACP_ANY = DataFactory.namedNode("http://www.w3.org/ns/solid/acp#anyOf"); const ACP_ALL = DataFactory.namedNode("http://www.w3.org/ns/solid/acp#allOf"); const ACP_NONE = DataFactory.namedNode("http://www.w3.org/ns/solid/acp#noneOf"); const RDF_TYPE = DataFactory.namedNode( "http://www.w3.org/1999/02/22-rdf-syntax-ns#type" ); const ACP_RULE = DataFactory.namedNode("http://www.w3.org/ns/solid/acp#Rule"); const ACP_AGENT = DataFactory.namedNode("http://www.w3.org/ns/solid/acp#agent"); const ACP_GROUP = DataFactory.namedNode("http://www.w3.org/ns/solid/acp#group"); const ACP_CLIENT = DataFactory.namedNode( "http://www.w3.org/ns/solid/acp#client" ); const ACP_PUBLIC = DataFactory.namedNode( "http://www.w3.org/ns/solid/acp#PublicAgent" ); const ACP_AUTHENTICATED = DataFactory.namedNode( "http://www.w3.org/ns/solid/acp#AuthenticatedAgent" ); const ACP_CREATOR = DataFactory.namedNode( "http://www.w3.org/ns/solid/acp#CreatorAgent" ); const SOLID_PUBLIC_CLIENT = DataFactory.namedNode( "http://www.w3.org/ns/solid/terms#PublicOidcClient" ); // Test data const MOCKED_POLICY_IRI = DataFactory.namedNode( "https://some.pod/policy-resource#policy" ); const MOCKED_RULE_IRI = DataFactory.namedNode( "https://some.pod/rule-resource#a-rule" ); const OTHER_MOCKED_RULE_IRI = DataFactory.namedNode( "https://some.pod/rule-resource#another-rule" ); const ALLOF_RULE_IRI = DataFactory.namedNode( "https://some.pod/rule-resource#allOf-rule" ); const ANYOF_RULE_IRI = DataFactory.namedNode( "https://some.pod/rule-resource#anyOf-rule" ); const NONEOF_RULE_IRI = DataFactory.namedNode( "https://some.pod/rule-resource#noneOf-rule" ); const MOCK_WEBID_ME = DataFactory.namedNode("https://my.pod/profile#me"); const MOCK_WEBID_YOU = DataFactory.namedNode("https://your.pod/profile#you"); const MOCK_GROUP_IRI = DataFactory.namedNode("https://my.pod/group#a-group"); const MOCK_GROUP_OTHER_IRI = DataFactory.namedNode( "https://my.pod/group#another-group" ); const MOCK_CLIENT_WEBID_1 = DataFactory.namedNode( "https://my.app/registration#it" ); const MOCK_CLIENT_WEBID_2 = DataFactory.namedNode( "https://your.app/registration#it" ); type ThingObject = ThingPersisted | Url | UrlString; function isNamedNode(object: ThingObject): object is Url { return typeof (object as Url).value !== undefined; } const addAllObjects = ( thing: ThingPersisted, predicate: NamedNode, objects: ThingObject[] ): void => { objects.forEach((objectToAdd) => { let objectUrl: string; if (isThing(objectToAdd)) { objectUrl = asIri(objectToAdd); } else if (isNamedNode(objectToAdd)) { // The object is an Url (aka NamedNode) objectUrl = objectToAdd.value; } else { objectUrl = objectToAdd; } thing.add( DataFactory.quad( DataFactory.namedNode(asIri(thing)), predicate, DataFactory.namedNode(objectUrl) ) ); }); }; const mockRule = ( url: Url, content?: { agents?: Url[]; groups?: Url[]; public?: boolean; authenticated?: boolean; creator?: boolean; clients?: Url[]; publicClient?: boolean; } ): Rule => { let mockedRule = createThing({ url: url.value, }); mockedRule = mockedRule.add( DataFactory.quad( DataFactory.namedNode(asIri(mockedRule)), RDF_TYPE, ACP_RULE ) ); if (content?.agents) { addAllObjects(mockedRule, ACP_AGENT, content.agents); } if (content?.groups) { addAllObjects(mockedRule, ACP_GROUP, content.groups); } if (content?.clients) { addAllObjects(mockedRule, ACP_CLIENT, content.clients); } if (content?.public) { mockedRule = mockedRule.add( DataFactory.quad( DataFactory.namedNode(asIri(mockedRule)), ACP_AGENT, ACP_PUBLIC ) ); } if (content?.authenticated) { mockedRule = mockedRule.add( DataFactory.quad( DataFactory.namedNode(asIri(mockedRule)), ACP_AGENT, ACP_AUTHENTICATED ) ); } if (content?.creator) { mockedRule = mockedRule.add( DataFactory.quad( DataFactory.namedNode(asIri(mockedRule)), ACP_AGENT, ACP_CREATOR ) ); } if (content?.publicClient) { mockedRule = mockedRule.add( DataFactory.quad( DataFactory.namedNode(asIri(mockedRule)), ACP_CLIENT, SOLID_PUBLIC_CLIENT ) ); } return mockedRule; }; const mockPolicy = ( url: NamedNode, rules?: { allOf?: Rule[]; anyOf?: Rule[]; noneOf?: Rule[] } ): Policy => { const mockPolicy = createThing({ url: url.value }); if (rules?.noneOf) { addAllObjects(mockPolicy, ACP_NONE, rules.noneOf); } if (rules?.anyOf) { addAllObjects(mockPolicy, ACP_ANY, rules.anyOf); } if (rules?.allOf) { addAllObjects(mockPolicy, ACP_ALL, rules.allOf); } return mockPolicy; }; describe("addNoneOfRuleUrl", () => { it("adds the rule in the noneOf rules of the policy", () => { const myPolicy = addNoneOfRuleUrl( mockPolicy(MOCKED_POLICY_IRI), mockRule(MOCKED_RULE_IRI) ); expect( myPolicy.has( DataFactory.quad(MOCKED_POLICY_IRI, ACP_NONE, MOCKED_RULE_IRI) ) ).toBe(true); }); it("does not remove the existing noneOf rules", () => { const mockedPolicy = mockPolicy(MOCKED_POLICY_IRI, { noneOf: [mockRule(OTHER_MOCKED_RULE_IRI)], }); const myPolicy = addNoneOfRuleUrl(mockedPolicy, mockRule(MOCKED_RULE_IRI)); expect( myPolicy.has( DataFactory.quad(MOCKED_POLICY_IRI, ACP_NONE, OTHER_MOCKED_RULE_IRI) ) ).toBe(true); }); it("does not change the existing allOf and anyOf rules", () => { const mockedPolicy = mockPolicy(MOCKED_POLICY_IRI, { anyOf: [mockRule(ANYOF_RULE_IRI)], allOf: [mockRule(ALLOF_RULE_IRI)], }); const myPolicy = addNoneOfRuleUrl(mockedPolicy, mockRule(NONEOF_RULE_IRI)); expect( myPolicy.has(DataFactory.quad(MOCKED_POLICY_IRI, ACP_ALL, ALLOF_RULE_IRI)) ).toBe(true); expect( myPolicy.has(DataFactory.quad(MOCKED_POLICY_IRI, ACP_ANY, ANYOF_RULE_IRI)) ).toBe(true); }); it("does not change the input policy", () => { const myPolicy = mockPolicy(MOCKED_POLICY_IRI); const mypolicySize = myPolicy.size; addNoneOfRuleUrl(myPolicy, mockRule(MOCKED_RULE_IRI)); expect(myPolicy.size).toBe(mypolicySize); }); }); describe("addAnyOfRuleUrl", () => { it("adds the rule in the anyOf rules of the policy", () => { const myPolicy = addAnyOfRuleUrl( mockPolicy(MOCKED_POLICY_IRI), mockRule(MOCKED_RULE_IRI) ); expect( myPolicy.has( DataFactory.quad(MOCKED_POLICY_IRI, ACP_ANY, MOCKED_RULE_IRI) ) ).toBe(true); }); it("does not remove the existing anyOf rules", () => { const mockedPolicy = mockPolicy(MOCKED_POLICY_IRI, { anyOf: [mockRule(OTHER_MOCKED_RULE_IRI)], }); const myPolicy = addAnyOfRuleUrl(mockedPolicy, mockRule(MOCKED_POLICY_IRI)); expect( myPolicy.has( DataFactory.quad(MOCKED_POLICY_IRI, ACP_ANY, OTHER_MOCKED_RULE_IRI) ) ).toBe(true); }); it("does not change the existing allOf and noneOf rules", () => { const mockedPolicy = mockPolicy(MOCKED_POLICY_IRI, { noneOf: [mockRule(NONEOF_RULE_IRI)], allOf: [mockRule(ALLOF_RULE_IRI)], }); const myPolicy = addAnyOfRuleUrl(mockedPolicy, mockRule(ANYOF_RULE_IRI)); expect( myPolicy.has(DataFactory.quad(MOCKED_POLICY_IRI, ACP_ALL, ALLOF_RULE_IRI)) ).toBe(true); expect( myPolicy.has( DataFactory.quad(MOCKED_POLICY_IRI, ACP_NONE, NONEOF_RULE_IRI) ) ).toBe(true); }); it("does not change the input policy", () => { const myPolicy = mockPolicy(MOCKED_POLICY_IRI); addAnyOfRuleUrl(myPolicy, mockRule(MOCKED_RULE_IRI)); expect(myPolicy.size).toBe(0); }); }); describe("addAllOfRule", () => { it("adds the rule in the allOf rules of the policy", () => { const myPolicy = addAllOfRuleUrl( mockPolicy(MOCKED_POLICY_IRI), mockRule(MOCKED_RULE_IRI) ); expect( myPolicy.has( DataFactory.quad(MOCKED_POLICY_IRI, ACP_ALL, MOCKED_RULE_IRI) ) ).toBe(true); }); it("does not remove the existing allOf rules", () => { const mockedPolicy = mockPolicy(MOCKED_POLICY_IRI, { allOf: [mockRule(OTHER_MOCKED_RULE_IRI)], }); const myPolicy = addAllOfRuleUrl(mockedPolicy, mockRule(MOCKED_RULE_IRI)); expect( myPolicy.has( DataFactory.quad(MOCKED_POLICY_IRI, ACP_ALL, OTHER_MOCKED_RULE_IRI) ) ).toBe(true); }); it("does not change the existing anyOf and noneOf rules", () => { const mockedPolicy = mockPolicy(MOCKED_POLICY_IRI, { noneOf: [mockRule(NONEOF_RULE_IRI)], anyOf: [mockRule(ANYOF_RULE_IRI)], }); const myPolicy = addAllOfRuleUrl(mockedPolicy, mockRule(ANYOF_RULE_IRI)); expect( myPolicy.has(DataFactory.quad(MOCKED_POLICY_IRI, ACP_ANY, ANYOF_RULE_IRI)) ).toBe(true); expect( myPolicy.has( DataFactory.quad(MOCKED_POLICY_IRI, ACP_NONE, NONEOF_RULE_IRI) ) ).toBe(true); }); it("does not change the input policy", () => { const myPolicy = mockPolicy(MOCKED_POLICY_IRI); addAnyOfRuleUrl(myPolicy, mockRule(MOCKED_RULE_IRI)); expect(myPolicy.size).toBe(0); }); }); describe("setNoneOfRuleUrl", () => { it("sets the provided rules as the noneOf rules for the policy", () => { const myPolicy = setNoneOfRuleUrl( mockPolicy(MOCKED_POLICY_IRI), mockRule(MOCKED_RULE_IRI) ); expect( myPolicy.has( DataFactory.quad(MOCKED_POLICY_IRI, ACP_NONE, MOCKED_RULE_IRI) ) ).toBe(true); }); it("removes any previous noneOf rules for on the policy", () => { const mockedPolicy = mockPolicy(MOCKED_POLICY_IRI, { noneOf: [mockRule(OTHER_MOCKED_RULE_IRI)], }); const myPolicy = setNoneOfRuleUrl(mockedPolicy, mockRule(MOCKED_RULE_IRI)); expect( myPolicy.has( DataFactory.quad(MOCKED_POLICY_IRI, ACP_NONE, OTHER_MOCKED_RULE_IRI) ) ).toBe(false); }); it("does not change the existing anyOf and allOf rules on the policy", () => { const mockedPolicy = mockPolicy(MOCKED_POLICY_IRI, { anyOf: [mockRule(ANYOF_RULE_IRI)], allOf: [mockRule(ALLOF_RULE_IRI)], }); const myPolicy = setNoneOfRuleUrl(mockedPolicy, mockRule(NONEOF_RULE_IRI)); expect( myPolicy.has(DataFactory.quad(MOCKED_POLICY_IRI, ACP_ALL, ALLOF_RULE_IRI)) ).toBe(true); expect( myPolicy.has(DataFactory.quad(MOCKED_POLICY_IRI, ACP_ANY, ANYOF_RULE_IRI)) ).toBe(true); }); it("does not change the input policy", () => { const myPolicy = mockPolicy(MOCKED_POLICY_IRI); setNoneOfRuleUrl(myPolicy, mockRule(MOCKED_RULE_IRI)); expect(myPolicy.size).toBe(0); }); }); describe("setAnyOfRuleUrl", () => { it("sets the provided rules as the anyOf rules for the policy", () => { const myPolicy = setAnyOfRuleUrl( mockPolicy(MOCKED_POLICY_IRI), mockRule(MOCKED_RULE_IRI) ); expect( myPolicy.has( DataFactory.quad(MOCKED_POLICY_IRI, ACP_ANY, MOCKED_RULE_IRI) ) ).toBe(true); }); it("removes any previous anyOf rules for on the policy", () => { const mockedPolicy = mockPolicy(MOCKED_POLICY_IRI, { anyOf: [mockRule(OTHER_MOCKED_RULE_IRI)], }); const myPolicy = setAnyOfRuleUrl(mockedPolicy, mockRule(MOCKED_RULE_IRI)); expect( myPolicy.has( DataFactory.quad(MOCKED_POLICY_IRI, ACP_ANY, OTHER_MOCKED_RULE_IRI) ) ).toBe(false); }); it("does not change the existing noneOf and allOf rules on the policy", () => { const mockedPolicy = mockPolicy(MOCKED_POLICY_IRI, { noneOf: [mockRule(NONEOF_RULE_IRI)], allOf: [mockRule(ALLOF_RULE_IRI)], }); const myPolicy = setAnyOfRuleUrl(mockedPolicy, mockRule(ANYOF_RULE_IRI)); expect( myPolicy.has(DataFactory.quad(MOCKED_POLICY_IRI, ACP_ALL, ALLOF_RULE_IRI)) ).toBe(true); expect( myPolicy.has( DataFactory.quad(MOCKED_POLICY_IRI, ACP_NONE, NONEOF_RULE_IRI) ) ).toBe(true); }); it("does not change the input policy", () => { const myPolicy = mockPolicy(MOCKED_POLICY_IRI); setAnyOfRuleUrl(myPolicy, mockRule(MOCKED_RULE_IRI)); expect(myPolicy.size).toBe(0); }); }); describe("setAllOfRuleUrl", () => { it("sets the provided rules as the allOf rules for the policy", () => { const myPolicy = setAllOfRuleUrl( mockPolicy(MOCKED_POLICY_IRI), mockRule(MOCKED_RULE_IRI) ); expect( myPolicy.has( DataFactory.quad(MOCKED_POLICY_IRI, ACP_ALL, MOCKED_RULE_IRI) ) ).toBe(true); }); it("removes any previous allOf rules for on the policy", () => { const mockedPolicy = mockPolicy(MOCKED_POLICY_IRI, { allOf: [mockRule(OTHER_MOCKED_RULE_IRI)], }); const myPolicy = setAllOfRuleUrl(mockedPolicy, mockRule(MOCKED_RULE_IRI)); expect( myPolicy.has( DataFactory.quad(MOCKED_POLICY_IRI, ACP_ALL, OTHER_MOCKED_RULE_IRI) ) ).toBe(false); }); it("does not change the existing noneOf and anyOf rules on the policy", () => { const mockedPolicy = mockPolicy(MOCKED_POLICY_IRI, { noneOf: [mockRule(NONEOF_RULE_IRI)], anyOf: [mockRule(ANYOF_RULE_IRI)], }); const myPolicy = setAllOfRuleUrl(mockedPolicy, mockRule(ALLOF_RULE_IRI)); expect( myPolicy.has(DataFactory.quad(MOCKED_POLICY_IRI, ACP_ANY, ANYOF_RULE_IRI)) ).toBe(true); expect( myPolicy.has( DataFactory.quad(MOCKED_POLICY_IRI, ACP_NONE, NONEOF_RULE_IRI) ) ).toBe(true); }); it("does not change the input policy", () => { const myPolicy = mockPolicy(MOCKED_POLICY_IRI); setAllOfRuleUrl(myPolicy, mockRule(MOCKED_RULE_IRI)); expect(myPolicy.size).toBe(0); }); }); describe("getNoneOfRuleurlAll", () => { it("returns all the noneOf rules for the given policy", () => { const mockedPolicy = mockPolicy(MOCKED_POLICY_IRI, { noneOf: [mockRule(MOCKED_RULE_IRI), mockRule(OTHER_MOCKED_RULE_IRI)], }); const noneOfRules = getNoneOfRuleUrlAll(mockedPolicy); expect(noneOfRules).toContain(MOCKED_RULE_IRI.value); expect(noneOfRules).toContain(OTHER_MOCKED_RULE_IRI.value); expect(noneOfRules).toHaveLength(2); }); it("returns only the noneOf rules for the given policy", () => { const mockedPolicy = mockPolicy(MOCKED_POLICY_IRI, { noneOf: [mockRule(NONEOF_RULE_IRI)], anyOf: [mockRule(ANYOF_RULE_IRI)], allOf: [mockRule(ALLOF_RULE_IRI)], }); const noneOfRules = getNoneOfRuleUrlAll(mockedPolicy); expect(noneOfRules).not.toContain(ANYOF_RULE_IRI.value); expect(noneOfRules).not.toContain(ALLOF_RULE_IRI.value); expect(noneOfRules).toHaveLength(1); }); }); describe("getAnyOfRulesOnPolicyAll", () => { it("returns all the anyOf rules for the given policy", () => { const mockedPolicy = mockPolicy(MOCKED_POLICY_IRI, { anyOf: [mockRule(MOCKED_RULE_IRI), mockRule(OTHER_MOCKED_RULE_IRI)], }); const anyOfRules = getAnyOfRuleUrlAll(mockedPolicy); expect(anyOfRules).toContain(MOCKED_RULE_IRI.value); expect(anyOfRules).toContain(OTHER_MOCKED_RULE_IRI.value); expect(anyOfRules).toHaveLength(2); }); it("returns only the anyOf rules for the given policy", () => { const mockedPolicy = mockPolicy(MOCKED_POLICY_IRI, { noneOf: [mockRule(NONEOF_RULE_IRI)], anyOf: [mockRule(ANYOF_RULE_IRI)], allOf: [mockRule(ALLOF_RULE_IRI)], }); const anyOfRules = getAnyOfRuleUrlAll(mockedPolicy); expect(anyOfRules).not.toContain(NONEOF_RULE_IRI.value); expect(anyOfRules).not.toContain(ALLOF_RULE_IRI.value); expect(anyOfRules).toHaveLength(1); }); }); describe("getAllOfRulesOnPolicyAll", () => { it("returns all the allOf rules for the given policy", () => { const mockedPolicy = mockPolicy(MOCKED_POLICY_IRI, { allOf: [mockRule(MOCKED_RULE_IRI), mockRule(OTHER_MOCKED_RULE_IRI)], }); const allOfRules = getAllOfRuleUrlAll(mockedPolicy); expect(allOfRules).toContain(MOCKED_RULE_IRI.value); expect(allOfRules).toContain(OTHER_MOCKED_RULE_IRI.value); expect(allOfRules).toHaveLength(2); }); it("returns only the allOf rules for the given policy", () => { const mockedPolicy = mockPolicy(MOCKED_POLICY_IRI, { noneOf: [mockRule(NONEOF_RULE_IRI)], anyOf: [mockRule(ANYOF_RULE_IRI)], allOf: [mockRule(ALLOF_RULE_IRI)], }); const allOfRules = getAllOfRuleUrlAll(mockedPolicy); expect(allOfRules).not.toContain(NONEOF_RULE_IRI.value); expect(allOfRules).not.toContain(ANYOF_RULE_IRI.value); expect(allOfRules).toHaveLength(1); }); }); describe("removeAllOfRule", () => { it("removes the rule from the allOf rules for the given policy", () => { const mockedRule = mockRule(MOCKED_RULE_IRI); const mockedPolicy = mockPolicy(MOCKED_POLICY_IRI, { allOf: [mockedRule], }); const result = removeAllOfRuleUrl(mockedPolicy, mockedRule); expect( result.has(DataFactory.quad(MOCKED_POLICY_IRI, ACP_ALL, MOCKED_RULE_IRI)) ).toBe(false); }); it("does not remove the rule from the anyOf/noneOf rules for the given policy", () => { const mockedRule = mockRule(MOCKED_RULE_IRI); const mockedPolicy = mockPolicy(MOCKED_POLICY_IRI, { anyOf: [mockedRule], noneOf: [mockedRule], }); const result = removeAllOfRuleUrl(mockedPolicy, mockedRule); expect( result.has(DataFactory.quad(MOCKED_POLICY_IRI, ACP_ANY, MOCKED_RULE_IRI)) ).toBe(true); expect( result.has(DataFactory.quad(MOCKED_POLICY_IRI, ACP_NONE, MOCKED_RULE_IRI)) ).toBe(true); }); }); describe("removeAnyOfRuleUrl", () => { it("removes the rule from the allOf rules for the given policy", () => { const mockedRule = mockRule(MOCKED_RULE_IRI); const mockedPolicy = mockPolicy(MOCKED_POLICY_IRI, { anyOf: [mockedRule], }); const result = removeAnyOfRuleUrl(mockedPolicy, mockedRule); expect( result.has(DataFactory.quad(MOCKED_POLICY_IRI, ACP_ANY, MOCKED_RULE_IRI)) ).toBe(false); }); it("does not remove the rule from the allOf/noneOf rules for the given policy", () => { const mockedRule = mockRule(MOCKED_RULE_IRI); const mockedPolicy = mockPolicy(MOCKED_POLICY_IRI, { allOf: [mockedRule], noneOf: [mockedRule], }); const result = removeAnyOfRuleUrl(mockedPolicy, mockedRule); expect( result.has(DataFactory.quad(MOCKED_POLICY_IRI, ACP_ALL, MOCKED_RULE_IRI)) ).toBe(true); expect( result.has(DataFactory.quad(MOCKED_POLICY_IRI, ACP_NONE, MOCKED_RULE_IRI)) ).toBe(true); }); }); describe("removeNoneOfRuleUrl", () => { it("removes the rule from the noneOf rules for the given policy", () => { const mockedRule = mockRule(MOCKED_RULE_IRI); const mockedPolicy = mockPolicy(MOCKED_POLICY_IRI, { noneOf: [mockedRule], }); const result = removeNoneOfRuleUrl(mockedPolicy, mockedRule); expect( result.has(DataFactory.quad(MOCKED_POLICY_IRI, ACP_NONE, MOCKED_RULE_IRI)) ).toBe(false); }); it("does not remove the rule from the allOf/anyOf rules for the given policy", () => { const mockedRule = mockRule(MOCKED_RULE_IRI); const mockedPolicy = mockPolicy(MOCKED_POLICY_IRI, { allOf: [mockedRule], anyOf: [mockedRule], }); const result = removeNoneOfRuleUrl(mockedPolicy, mockedRule); expect( result.has(DataFactory.quad(MOCKED_POLICY_IRI, ACP_ALL, MOCKED_RULE_IRI)) ).toBe(true); expect( result.has(DataFactory.quad(MOCKED_POLICY_IRI, ACP_ANY, MOCKED_RULE_IRI)) ).toBe(true); }); }); describe("createRule", () => { it("returns a acp:Rule", () => { const myRule = createRule(MOCKED_RULE_IRI.value); expect( myRule.has(DataFactory.quad(MOCKED_RULE_IRI, RDF_TYPE, ACP_RULE)) ).toBe(true); }); it("returns an **empty** rule", () => { const myRule = createRule("https://my.pod/rule-resource#rule"); // The rule should only contain a type triple. expect(myRule.size).toBe(1); }); }); describe("createResourceRuleFor", () => { it("returns a acp:Rule", () => { const mockedAcr = mockAcrFor("https://some.pod/resource"); const mockedResourceWithAcr = addMockAcrTo( mockSolidDatasetFrom("https://some.pod/resource"), mockedAcr ); const myRule = createResourceRuleFor(mockedResourceWithAcr, "myRule"); expect(getIri(myRule, RDF_TYPE)).toBe(ACP_RULE.value); }); it("returns an **empty** rule", () => { const mockedAcr = mockAcrFor("https://some.pod/resource"); const mockedResourceWithAcr = addMockAcrTo( mockSolidDatasetFrom("https://some.pod/resource"), mockedAcr ); const myRule = createResourceRuleFor(mockedResourceWithAcr, "myRule"); // The rule should only contain a type triple. expect(myRule.size).toBe(1); }); }); describe("getRule", () => { it("returns the rule with a matching IRI", () => { const rule = mockRule(MOCKED_RULE_IRI); const dataset = setThing(createSolidDataset(), rule); const result = getRule(dataset, MOCKED_RULE_IRI.value); expect(result).not.toBeNull(); }); it("does not return a Thing with a matching IRI but the wrong type", () => { const notARule = createThing({ url: "https://my.pod/rule-resource#not-a-rule", }); const dataset = setThing( createSolidDataset(), setUrl(notARule, RDF_TYPE, "http://example.org/ns#NotRuleType") ); const result = getRule(dataset, "https://my.pod/rule-resource#not-a-rule"); expect(result).toBeNull(); }); it("does not return a rule with a mismatching IRI", () => { const rule = mockRule(MOCKED_RULE_IRI); const dataset = setThing(createSolidDataset(), rule); const result = getRule(dataset, OTHER_MOCKED_RULE_IRI); expect(result).toBeNull(); }); }); describe("getResourceRule", () => { it("returns the rule with a matching name", () => { let mockedAcr = mockAcrFor("https://some.pod/resource"); let mockedRule = createThing({ url: `${getSourceUrl(mockedAcr)}#rule`, }); mockedRule = setUrl(mockedRule, rdf.type, acp.Rule); mockedAcr = setThing(mockedAcr, mockedRule); const mockedResourceWithAcr = addMockAcrTo( mockSolidDatasetFrom("https://some.pod/resource"), mockedAcr ); const result = getResourceRule(mockedResourceWithAcr, "rule"); expect(result).not.toBeNull(); }); it("does not return a Thing with a matching IRI but the wrong type", () => { let mockedAcr = mockAcrFor("https://some.pod/resource"); let mockedRule = createThing({ url: `${getSourceUrl(mockedAcr)}#rule`, }); mockedRule = setUrl( mockedRule, rdf.type, "http://example.org/ns#NotRuleType" ); mockedAcr = setThing(mockedAcr, mockedRule); const mockedResourceWithAcr = addMockAcrTo( mockSolidDatasetFrom("https://some.pod/resource"), mockedAcr ); const result = getResourceRule(mockedResourceWithAcr, "rule"); expect(result).toBeNull(); }); it("does not return a rule with a mismatching IRI", () => { let mockedAcr = mockAcrFor("https://some.pod/resource"); let mockedRule = createThing({ url: `${getSourceUrl(mockedAcr)}#rule`, }); mockedRule = setUrl(mockedRule, rdf.type, acp.Rule); mockedAcr = setThing(mockedAcr, mockedRule); const mockedResourceWithAcr = addMockAcrTo( mockSolidDatasetFrom("https://some.pod/resource"), mockedAcr ); const result = getResourceRule(mockedResourceWithAcr, "other-rule"); expect(result).toBeNull(); }); }); describe("getRuleAll", () => { it("returns an empty array if there are no Rules in the given Dataset", () => { expect(getRuleAll(createSolidDataset())).toHaveLength(0); }); it("returns all the rules in a rule resource", () => { const rule = mockRule(MOCKED_RULE_IRI); const dataset = setThing(createSolidDataset(), rule); let result = getRuleAll(dataset); expect(result).toHaveLength(1); const anotherRule = mockRule(OTHER_MOCKED_RULE_IRI); const newDataset = setThing(dataset, anotherRule); result = getRuleAll(newDataset); expect(result).toHaveLength(2); }); }); describe("getResourceRuleAll", () => { it("returns an empty array if there are no Rules in the given Resource's ACR", () => { const mockedAcr = mockAcrFor("https://some.pod/resource"); const mockedResourceWithAcr = addMockAcrTo( mockSolidDatasetFrom("https://some.pod/resource"), mockedAcr ); expect(getResourceRuleAll(mockedResourceWithAcr)).toHaveLength(0); }); it("returns all the rules in a Resource's ACR", () => { let mockedAcr = mockAcrFor("https://some.pod/resource"); let mockedRule1 = createThing({ url: `${getSourceUrl(mockedAcr)}#rule1`, }); mockedRule1 = setUrl(mockedRule1, rdf.type, acp.Rule); let mockedRule2 = createThing({ url: `${getSourceUrl(mockedAcr)}#rule2`, }); mockedRule2 = setUrl(mockedRule2, rdf.type, acp.Rule); mockedAcr = setThing(mockedAcr, mockedRule1); mockedAcr = setThing(mockedAcr, mockedRule2); const mockedResourceWithAcr = addMockAcrTo( mockSolidDatasetFrom("https://some.pod/resource"), mockedAcr ); const result = getResourceRuleAll(mockedResourceWithAcr); expect(result).toHaveLength(2); }); }); describe("removeRule", () => { it("removes the Rule from the given empty Dataset", () => { const rule = mockRule(MOCKED_RULE_IRI); const dataset = setThing(createSolidDataset(), rule); const updatedDataset = removeRule(dataset, MOCKED_RULE_IRI); expect(getThingAll(updatedDataset)).toHaveLength(0); }); }); describe("removeResourceRule", () => { it("removes the Rule from the given Resource's Access control Resource", () => { let mockedAcr = mockAcrFor("https://some.pod/resource"); let mockedRule = createThing({ url: `${getSourceUrl(mockedAcr)}#rule`, }); mockedRule = setUrl(mockedRule, rdf.type, acp.Rule); mockedAcr = setThing(mockedAcr, mockedRule); const mockedResourceWithAcr = addMockAcrTo( mockSolidDatasetFrom("https://some.pod/resource"), mockedAcr ); const updatedDataset = removeResourceRule( mockedResourceWithAcr, mockedRule ); expect(getResourceRuleAll(updatedDataset)).toHaveLength(0); }); it("accepts a plain name to remove a Rule", () => { let mockedAcr = mockAcrFor("https://some.pod/resource"); let mockedRule = createThing({ url: `${getSourceUrl(mockedAcr)}#rule`, }); mockedRule = setUrl(mockedRule, rdf.type, acp.Rule); mockedAcr = setThing(mockedAcr, mockedRule); const mockedResourceWithAcr = addMockAcrTo( mockSolidDatasetFrom("https://some.pod/resource"), mockedAcr ); const updatedDataset = removeResourceRule(mockedResourceWithAcr, "rule"); expect(getResourceRuleAll(updatedDataset)).toHaveLength(0); }); it("accepts a full URL to remove a Rule", () => { let mockedAcr = mockAcrFor("https://some.pod/resource"); let mockedRule = createThing({ url: `${getSourceUrl(mockedAcr)}#rule`, }); mockedRule = setUrl(mockedRule, rdf.type, acp.Rule); mockedAcr = setThing(mockedAcr, mockedRule); const mockedResourceWithAcr = addMockAcrTo( mockSolidDatasetFrom("https://some.pod/resource"), mockedAcr ); const updatedDataset = removeResourceRule( mockedResourceWithAcr, `${getSourceUrl(mockedAcr)}#rule` ); expect(getResourceRuleAll(updatedDataset)).toHaveLength(0); }); it("accepts a Named Node to remove a Rule", () => { let mockedAcr = mockAcrFor("https://some.pod/resource"); let mockedRule = createThing({ url: `${getSourceUrl(mockedAcr)}#rule`, }); mockedRule = setUrl(mockedRule, rdf.type, acp.Rule); mockedAcr = setThing(mockedAcr, mockedRule); const mockedResourceWithAcr = addMockAcrTo( mockSolidDatasetFrom("https://some.pod/resource"), mockedAcr ); const updatedDataset = removeResourceRule( mockedResourceWithAcr, DataFactory.namedNode(`${getSourceUrl(mockedAcr)}#rule`) ); expect(getResourceRuleAll(updatedDataset)).toHaveLength(0); }); it("does not remove a non-Rule with the same name", () => { let mockedAcr = mockAcrFor("https://some.pod/resource"); let mockedRule = createThing({ url: `${getSourceUrl(mockedAcr)}#rule`, }); mockedRule = setUrl( mockedRule, rdf.type, "https://example.vocab/not-a-rule" ); mockedAcr = setThing(mockedAcr, mockedRule); const mockedResourceWithAcr = addMockAcrTo( mockSolidDatasetFrom("https://some.pod/resource"), mockedAcr ); const updatedDataset = removeResourceRule(mockedResourceWithAcr, "rule"); const updatedAcr = internal_getAcr(updatedDataset); expect( getThing(updatedAcr, `${getSourceUrl(mockedAcr)}#rule`) ).not.toBeNull(); }); }); describe("setRule", () => { it("sets the Rule in the given empty Dataset", () => { const rule = mockRule(MOCKED_RULE_IRI); const dataset = setRule(createSolidDataset(), rule); const result = getThing(dataset, MOCKED_RULE_IRI); expect(result).not.toBeNull(); expect(getIriAll(result as Thing, rdf.type)).toContain(acp.Rule); }); }); describe("setResourceRule", () => { it("sets the Rule in the given Resource's ACR", () => { const mockedAcr = mockAcrFor("https://some.pod/resource"); const mockedResourceWithAcr = addMockAcrTo( mockSolidDatasetFrom("https://some.pod/resource"), mockedAcr ); let mockedRule = createThing({ url: `${getSourceUrl(mockedAcr)}#rule`, }); mockedRule = setUrl(mockedRule, rdf.type, acp.Rule); const updatedResource = setResourceRule(mockedResourceWithAcr, mockedRule); expect(getResourceRuleAll(updatedResource)).toHaveLength(1); }); }); describe("getAgentAll", () => { it("returns all the agents a rule applies to by WebID", () => { const rule = mockRule(MOCKED_RULE_IRI, { agents: [MOCK_WEBID_ME, MOCK_WEBID_YOU], }); const agents = getAgentAll(rule); expect(agents).toContain(MOCK_WEBID_ME.value); expect(agents).toContain(MOCK_WEBID_YOU.value); expect(agents).toHaveLength(2); }); it("does not return the groups/public/authenticated/creator/clients a rule applies to", () => { const rule = mockRule(MOCKED_RULE_IRI, { groups: [MOCK_GROUP_IRI], public: true, authenticated: true, creator: true, clients: [MOCK_CLIENT_WEBID_1], }); const agents = getAgentAll(rule); expect(agents).not.toContain(MOCK_GROUP_IRI.value); expect(agents).not.toContain(ACP_CREATOR.value); expect(agents).not.toContain(ACP_AUTHENTICATED.value); expect(agents).not.toContain(ACP_PUBLIC.value); expect(agents).toHaveLength(0); }); }); describe("setAgent", () => { it("sets the given agents for the rule", () => { const rule = mockRule(MOCKED_RULE_IRI); const result = setAgent(rule, MOCK_WEBID_ME.value); expect( result.has(DataFactory.quad(MOCKED_RULE_IRI, ACP_AGENT, MOCK_WEBID_ME)) ).toBe(true); }); it("deletes any agents previously set for the rule", () => { const rule = mockRule(MOCKED_RULE_IRI, { agents: [MOCK_WEBID_YOU], }); const result = setAgent(rule, MOCK_WEBID_ME.value); expect( result.has(DataFactory.quad(MOCKED_RULE_IRI, ACP_AGENT, MOCK_WEBID_ME)) ).toBe(true); expect( result.has(DataFactory.quad(MOCKED_RULE_IRI, ACP_AGENT, MOCK_WEBID_YOU)) ).toBe(false); }); it("does not change the input rule", () => { const rule = mockRule(MOCKED_RULE_IRI, { agents: [MOCK_WEBID_YOU], }); setAgent(rule, MOCK_WEBID_ME.value); expect( rule.has(DataFactory.quad(MOCKED_RULE_IRI, ACP_AGENT, MOCK_WEBID_ME)) ).toBe(false); expect( rule.has(DataFactory.quad(MOCKED_RULE_IRI, ACP_AGENT, MOCK_WEBID_YOU)) ).toBe(true); }); it("does not overwrite public, authenticated and creator agents", () => { const rule = mockRule(MOCKED_RULE_IRI, { public: true, authenticated: true, creator: true, }); const result = setAgent(rule, MOCK_WEBID_YOU.value); expect( result.has(DataFactory.quad(MOCKED_RULE_IRI, ACP_AGENT, ACP_PUBLIC)) ).toBe(true); expect( result.has( DataFactory.quad(MOCKED_RULE_IRI, ACP_AGENT, ACP_AUTHENTICATED) ) ).toBe(true); expect( result.has(DataFactory.quad(MOCKED_RULE_IRI, ACP_AGENT, ACP_CREATOR)) ).toBe(true); }); }); describe("addAgent", () => { it("adds the given agent to the rule", () => { const rule = mockRule(MOCKED_RULE_IRI); const result = addAgent(rule, MOCK_WEBID_YOU.value); expect( result.has(DataFactory.quad(MOCKED_RULE_IRI, ACP_AGENT, MOCK_WEBID_YOU)) ).toBe(true); }); it("does not override existing agents/public/authenticated/groups", () => { const rule = mockRule(MOCKED_RULE_IRI, { agents: [MOCK_WEBID_ME], groups: [MOCK_GROUP_IRI], public: true, authenticated: true, }); const result = addAgent(rule, MOCK_WEBID_YOU.value); expect( result.has(DataFactory.quad(MOCKED_RULE_IRI, ACP_AGENT, MOCK_WEBID_YOU)) ).toBe(true); expect( result.has(DataFactory.quad(MOCKED_RULE_IRI, ACP_AGENT, MOCK_WEBID_ME)) ).toBe(true); expect( result.has(DataFactory.quad(MOCKED_RULE_IRI, ACP_AGENT, ACP_PUBLIC)) ).toBe(true); expect( result.has( DataFactory.quad(MOCKED_RULE_IRI, ACP_AGENT, ACP_AUTHENTICATED) ) ).toBe(true); expect( result.has(DataFactory.quad(MOCKED_RULE_IRI, ACP_GROUP, MOCK_GROUP_IRI)) ).toBe(true); }); }); describe("removeAgent", () => { it("removes the given agent from the rule", () => { const rule = mockRule(MOCKED_RULE_IRI, { agents: [MOCK_WEBID_YOU], }); const result = removeAgent(rule, MOCK_WEBID_YOU.value); expect( result.has(DataFactory.quad(MOCKED_RULE_IRI, ACP_AGENT, MOCK_WEBID_YOU)) ).toBe(false); }); it("does not delete unrelated agents", () => { const rule = mockRule(MOCKED_RULE_IRI, { agents: [MOCK_WEBID_ME, MOCK_WEBID_YOU], public: true, authenticated: true, }); const result = removeAgent(rule, MOCK_WEBID_YOU.value); expect( result.has(DataFactory.quad(MOCKED_RULE_IRI, ACP_AGENT, MOCK_WEBID_YOU)) ).toBe(false); expect( result.has(DataFactory.quad(MOCKED_RULE_IRI, ACP_AGENT, MOCK_WEBID_ME)) ).toBe(true); expect( result.has(DataFactory.quad(MOCKED_RULE_IRI, ACP_AGENT, ACP_PUBLIC)) ).toBe(true); expect( result.has( DataFactory.quad(MOCKED_RULE_IRI, ACP_AGENT, ACP_AUTHENTICATED) ) ).toBe(true); }); it("does not remove groups, even with matching IRI", () => { const rule = mockRule(MOCKED_RULE_IRI, { groups: [MOCK_GROUP_IRI], }); const result = removeAgent(rule, MOCK_GROUP_IRI.value); expect( result.has(DataFactory.quad(MOCKED_RULE_IRI, ACP_GROUP, MOCK_GROUP_IRI)) ).toBe(true); }); }); describe("getGroupAll", () => { it("returns all the groups a rule applies to", () => { const rule = mockRule(MOCKED_RULE_IRI, { groups: [MOCK_GROUP_IRI, MOCK_GROUP_OTHER_IRI], }); const groups = getGroupAll(rule); expect(groups).toContain(MOCK_GROUP_IRI.value); expect(groups).toContain(MOCK_GROUP_OTHER_IRI.value); expect(groups).toHaveLength(2); }); it("does not return the agents/public/authenticated/clients a rule applies to", () => { const rule = mockRule(MOCKED_RULE_IRI, { agents: [MOCK_WEBID_ME], public: true, authenticated: true, clients: [MOCK_CLIENT_WEBID_1], }); const groups = getGroupAll(rule); expect(groups).not.toContain(MOCK_WEBID_ME.value); expect(groups).not.toContain(ACP_AUTHENTICATED.value); expect(groups).not.toContain(ACP_PUBLIC.value); expect(groups).toHaveLength(0); }); }); describe("setGroup", () => { it("sets the given groups for the rule", () => { const rule = mockRule(MOCKED_RULE_IRI); const result = setGroup(rule, MOCK_GROUP_IRI.value); expect( result.has(DataFactory.quad(MOCKED_RULE_IRI, ACP_GROUP, MOCK_GROUP_IRI)) ).toBe(true); }); it("deletes any groups previously set for the rule", () => { const rule = mockRule(MOCKED_RULE_IRI, { groups: [MOCK_GROUP_OTHER_IRI], }); const result = setGroup(rule, MOCK_GROUP_IRI.value); expect( result.has(DataFactory.quad(MOCKED_RULE_IRI, ACP_GROUP, MOCK_GROUP_IRI)) ).toBe(true); expect( result.has( DataFactory.quad(MOCKED_RULE_IRI, ACP_GROUP, MOCK_GROUP_OTHER_IRI) ) ).toBe(false); }); it("does not change the input rule", () => { const rule = mockRule(MOCKED_RULE_IRI, { groups: [MOCK_GROUP_OTHER_IRI], }); setGroup(rule, MOCK_GROUP_IRI.value); expect( rule.has(DataFactory.quad(MOCKED_RULE_IRI, ACP_GROUP, MOCK_GROUP_IRI)) ).toBe(false); expect( rule.has( DataFactory.quad(MOCKED_RULE_IRI, ACP_GROUP, MOCK_GROUP_OTHER_IRI) ) ).toBe(true); }); }); describe("addGroup", () => { it("adds the given group to the rule", () => { const rule = mockRule(MOCKED_RULE_IRI); const result = addGroup(rule, "https://your.pod/groups#a-group"); expect( result.has( DataFactory.quad( MOCKED_RULE_IRI, ACP_GROUP, DataFactory.namedNode("https://your.pod/groups#a-group") ) ) ).toBe(true); }); it("does not override existing agents/public/authenticated/groups", () => { const rule = mockRule(MOCKED_RULE_IRI, { agents: [MOCK_WEBID_ME], groups: [MOCK_GROUP_IRI], public: true, authenticated: true, }); const result = addGroup(rule, MOCK_GROUP_OTHER_IRI.value); expect( result.has( DataFactory.quad(MOCKED_RULE_IRI, ACP_GROUP, MOCK_GROUP_OTHER_IRI) ) ).toBe(true); expect( result.has(DataFactory.quad(MOCKED_RULE_IRI, ACP_AGENT, MOCK_WEBID_ME)) ).toBe(true); expect( result.has(DataFactory.quad(MOCKED_RULE_IRI, ACP_AGENT, ACP_PUBLIC)) ).toBe(true); expect( result.has( DataFactory.quad(MOCKED_RULE_IRI, ACP_AGENT, ACP_AUTHENTICATED) ) ).toBe(true); expect( result.has(DataFactory.quad(MOCKED_RULE_IRI, ACP_GROUP, MOCK_GROUP_IRI)) ).toBe(true); }); }); describe("removeGroup", () => { it("removes the given group from the rule", () => { const rule = mockRule(MOCKED_RULE_IRI, { groups: [MOCK_GROUP_IRI], }); const result = removeGroup(rule, MOCK_GROUP_IRI.value); expect( result.has(DataFactory.quad(MOCKED_RULE_IRI, ACP_GROUP, MOCK_GROUP_IRI)) ).toBe(false); }); it("does not delete unrelated groups", () => { const rule = mockRule(MOCKED_RULE_IRI, { groups: [MOCK_GROUP_IRI, MOCK_GROUP_OTHER_IRI], }); const result = removeGroup(rule, MOCK_GROUP_IRI.value); expect( result.has(DataFactory.quad(MOCKED_RULE_IRI, ACP_GROUP, MOCK_GROUP_IRI)) ).toBe(false); expect( result.has( DataFactory.quad(MOCKED_RULE_IRI, ACP_GROUP, MOCK_GROUP_OTHER_IRI) ) ).toBe(true); }); it("does not remove agents, even with matching IRI", () => { const rule = mockRule(MOCKED_RULE_IRI, { agents: [MOCK_WEBID_ME], }); const result = removeGroup(rule, MOCK_WEBID_ME.value); expect( result.has(DataFactory.quad(MOCKED_RULE_IRI, ACP_AGENT, MOCK_WEBID_ME)) ).toBe(true); }); }); describe("hasPublic", () => { it("returns true if the rule applies to the public agent", () => { const rule = mockRule(MOCKED_RULE_IRI, { public: true, }); expect(hasPublic(rule)).toBe(true); }); it("returns false if the rule only applies to other agent", () => { const rule = mockRule(MOCKED_RULE_IRI, { public: false, authenticated: true, agents: [MOCK_WEBID_ME], }); expect(hasPublic(rule)).toBe(false); }); }); describe("setPublic", () => { it("applies the given rule to the public agent", () => { const rule = mockRule(MOCKED_RULE_IRI); const result = setPublic(rule); expect( result.has(DataFactory.quad(MOCKED_RULE_IRI, ACP_AGENT, ACP_PUBLIC)) ).toBe(true); }); it("does not change the input rule", () => { const rule = mockRule(MOCKED_RULE_IRI); setPublic(rule); expect( rule.has(DataFactory.quad(MOCKED_RULE_IRI, ACP_AGENT, ACP_PUBLIC)) ).toBe(false); }); it("does not change the other agents", () => { const rule = mockRule(MOCKED_RULE_IRI, { authenticated: true, agents: [MOCK_WEBID_ME], }); const result = setPublic(rule); expect( result.has( DataFactory.quad(MOCKED_RULE_IRI, ACP_AGENT, ACP_AUTHENTICATED) ) ).toBe(true); expect( result.has(DataFactory.quad(MOCKED_RULE_IRI, ACP_AGENT, MOCK_WEBID_ME)) ).toBe(true); }); it("throws an error when you attempt to use the deprecated API", () => { const rule = mockRule(MOCKED_RULE_IRI); expect( // @ts-expect-error The type signature should warn about passing a second argument: () => setPublic(rule, true) ).toThrow( "The function `setPublic` no longer takes a second parameter. It is now used together with `removePublic` instead." ); }); }); describe("removePublic", () => { it("prevents the rule from applying to the public agent", () => { const rule = mockRule(MOCKED_RULE_IRI, { public: true, }); const result = removePublic(rule); expect( result.has(DataFactory.quad(MOCKED_RULE_IRI, ACP_AGENT, ACP_PUBLIC)) ).toBe(false); }); it("does not change the input rule", () => { const rule = mockRule(MOCKED_RULE_IRI, { public: true }); removePublic(rule); expect( rule.has(DataFactory.quad(MOCKED_RULE_IRI, ACP_AGENT, ACP_PUBLIC)) ).toBe(true); }); it("does not change the other agents", () => { const rule = mockRule(MOCKED_RULE_IRI, { authenticated: true, agents: [MOCK_WEBID_ME], public: true, }); const result = removePublic(rule); expect( result.has( DataFactory.quad(MOCKED_RULE_IRI, ACP_AGENT, ACP_AUTHENTICATED) ) ).toBe(true); expect( result.has(DataFactory.quad(MOCKED_RULE_IRI, ACP_AGENT, MOCK_WEBID_ME)) ).toBe(true); }); }); describe("hasAuthenticated", () => { it("returns true if the rule applies to authenticated agents", () => { const rule = mockRule(MOCKED_RULE_IRI, { authenticated: true, }); expect(hasAuthenticated(rule)).toBe(true); }); it("returns false if the rule only applies to other agent", () => { const rule = mockRule(MOCKED_RULE_IRI, { public: true, authenticated: false, agents: [MOCK_WEBID_ME], }); expect(hasAuthenticated(rule)).toBe(false); }); }); describe("setAuthenticated", () => { it("applies to given rule to authenticated agents", () => { const rule = mockRule(MOCKED_RULE_IRI); const result = setAuthenticated(rule); expect( result.has( DataFactory.quad(MOCKED_RULE_IRI, ACP_AGENT, ACP_AUTHENTICATED) ) ).toBe(true); }); it("does not change the input rule", () => { const rule = mockRule(MOCKED_RULE_IRI); setAuthenticated(rule); expect( rule.has(DataFactory.quad(MOCKED_RULE_IRI, ACP_AGENT, ACP_AUTHENTICATED)) ).toBe(false); }); it("does not change the other agents", () => { const rule = mockRule(MOCKED_RULE_IRI, { public: true, agents: [MOCK_WEBID_ME], }); const result = setAuthenticated(rule); expect( result.has(DataFactory.quad(MOCKED_RULE_IRI, ACP_AGENT, ACP_PUBLIC)) ).toBe(true); expect( result.has(DataFactory.quad(MOCKED_RULE_IRI, ACP_AGENT, MOCK_WEBID_ME)) ).toBe(true); }); it("throws an error when you attempt to use the deprecated API", () => { const rule = mockRule(MOCKED_RULE_IRI); expect( // @ts-expect-error The type signature should warn about passing a second argument: () => setAuthenticated(rule, true) ).toThrow( "The function `setAuthenticated` no longer takes a second parameter. It is now used together with `removeAuthenticated` instead." ); }); }); describe("removeAuthenticated", () => { it("prevents the rule from applying to authenticated agents", () => { const rule = mockRule(MOCKED_RULE_IRI, { authenticated: true, }); const result = removeAuthenticated(rule); expect( result.has( DataFactory.quad(MOCKED_RULE_IRI, ACP_AGENT, ACP_AUTHENTICATED) ) ).toBe(false); }); it("does not change the input rule", () => { const rule = mockRule(MOCKED_RULE_IRI, { authenticated: true }); removeAuthenticated(rule); expect( rule.has(DataFactory.quad(MOCKED_RULE_IRI, ACP_AGENT, ACP_AUTHENTICATED)) ).toBe(true); }); it("does not change the other agents", () => { const rule = mockRule(MOCKED_RULE_IRI, { public: true, authenticated: true, agents: [MOCK_WEBID_ME], }); const result = removeAuthenticated(rule); expect( result.has(DataFactory.quad(MOCKED_RULE_IRI, ACP_AGENT, ACP_PUBLIC)) ).toBe(true); expect( result.has(DataFactory.quad(MOCKED_RULE_IRI, ACP_AGENT, MOCK_WEBID_ME)) ).toBe(true); }); }); describe("hasCreator", () => { it("returns true if the rule applies to the Resource's creator", () => { const rule = mockRule(MOCKED_RULE_IRI, { creator: true, }); expect(hasCreator(rule)).toBe(true); }); it("returns false if the rule only applies to other agents", () => { const rule = mockRule(MOCKED_RULE_IRI, { public: true, creator: false, agents: [MOCK_WEBID_ME], }); expect(hasCreator(rule)).toBe(false); }); }); describe("setCreator", () => { it("applies the given rule to the Resource's creator", () => { const rule = mockRule(MOCKED_RULE_IRI); const result = setCreator(rule); expect( result.has(DataFactory.quad(MOCKED_RULE_IRI, ACP_AGENT, ACP_CREATOR)) ).toBe(true); }); it("does not change the input rule", () => { const rule = mockRule(MOCKED_RULE_IRI); setCreator(rule); expect( rule.has(DataFactory.quad(MOCKED_RULE_IRI, ACP_AGENT, ACP_CREATOR)) ).toBe(false); }); it("does not change the other agents", () => { const rule = mockRule(MOCKED_RULE_IRI, { public: true, agents: [MOCK_WEBID_ME], }); const result = setCreator(rule); expect( result.has(DataFactory.quad(MOCKED_RULE_IRI, ACP_AGENT, ACP_PUBLIC)) ).toBe(true); expect( result.has(DataFactory.quad(MOCKED_RULE_IRI, ACP_AGENT, MOCK_WEBID_ME)) ).toBe(true); }); it("throws an error when you attempt to use the deprecated API", () => { const rule = mockRule(MOCKED_RULE_IRI); expect( // @ts-expect-error The type signature should warn about passing a second argument: