@inrupt/solid-client
Version:
Make your web apps work with Solid Pods.
1,580 lines (1,460 loc) • 60.3 kB
text/typescript
/**
* 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: