Skip to content

Commit

Permalink
extract more helper methods and allow to configure rdflib store, fetc…
Browse files Browse the repository at this point in the history
…her and updater from outside the module
  • Loading branch information
angelo-v committed Nov 29, 2023
1 parent e585abc commit d3a726d
Show file tree
Hide file tree
Showing 8 changed files with 129 additions and 41 deletions.
6 changes: 5 additions & 1 deletion contacts/examples/create-address-book.mjs
Original file line number Diff line number Diff line change
@@ -1,6 +1,10 @@
import {ContactsModule} from '../dist/rdflib/index.js';
import {Fetcher, graph, UpdateManager} from "rdflib";

const contacts = new ContactsModule({})
const store = graph()
const fetcher = new Fetcher(store)
const updater = new UpdateManager(store)
const contacts = new ContactsModule({store, fetcher, updater})

const uri = await contacts.createAddressBook({
container: "http://localhost:3000/alice/public-write/",
Expand Down
6 changes: 5 additions & 1 deletion contacts/examples/read-address-book.mjs
Original file line number Diff line number Diff line change
@@ -1,6 +1,10 @@
import {ContactsModule} from '../dist/rdflib/index.js';
import {Fetcher, graph, UpdateManager} from "rdflib";

const contacts = new ContactsModule({})
const store = graph()
const fetcher = new Fetcher(store)
const updater = new UpdateManager(store)
const contacts = new ContactsModule({store, fetcher, updater})

const result = await contacts.readAddressBook("http://localhost:3000/alice/public-contacts/index.ttl#this")
console.log(result)
4 changes: 0 additions & 4 deletions contacts/src/index.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,3 @@
export interface ModuleConfig {
fetch: typeof global.fetch;
}

export interface ContactsModule {
readAddressBook(uri: string): Promise<AddressBook>;
}
Expand Down
57 changes: 57 additions & 0 deletions contacts/src/rdflib/ContactsModuleRdfLib.spec.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
import { when } from "jest-when";
import { createAddressBook } from "./createAddressBook";
import { ContactsModuleRdfLib } from "./ContactsModuleRdfLib";
import { executeUpdate } from "./executeUpdate";
import { Fetcher, graph, UpdateManager } from "rdflib";

jest.mock("./createAddressBook");
jest.mock("./executeUpdate");

describe("ContactsModuleRdfLib", () => {
describe("createAddressBook", () => {
const fakeOperation = {
uri: "https://pod.test/alice/118b9dc2-dacb-42e4-9d8c-6078aa832f51/index.ttl#this",
insertions: [],
deletions: [],
filesToCreate: [],
};

let result: string;
let fetcher: Fetcher;
let updater: UpdateManager;
beforeEach(async () => {
jest.clearAllMocks();
// given
when(createAddressBook)
.calledWith("https://pod.test/alice/", "My Contacts")
.mockReturnValue(fakeOperation);

const store = graph();
fetcher = new Fetcher(store);
updater = new UpdateManager(store);
const module = new ContactsModuleRdfLib({ store, fetcher, updater });

// when
result = await module.createAddressBook({
container: "https://pod.test/alice/",
name: "My Contacts",
});
});

it("returns the created URI", () => {
// then
expect(result).toEqual(
"https://pod.test/alice/118b9dc2-dacb-42e4-9d8c-6078aa832f51/index.ttl#this",
);
});

it("executes the update operation", () => {
// then
expect(executeUpdate).toHaveBeenCalledWith(
fetcher,
updater,
fakeOperation,
);
});
});
});
41 changes: 16 additions & 25 deletions contacts/src/rdflib/ContactsModuleRdfLib.ts
Original file line number Diff line number Diff line change
@@ -1,29 +1,29 @@
import {
Fetcher,
graph,
IndexedFormula,
Node,
sym,
UpdateManager,
} from "rdflib";
import { AddressBook, ContactsModule, ModuleConfig } from "..";
import { Fetcher, IndexedFormula, Node, sym, UpdateManager } from "rdflib";
import { AddressBook, ContactsModule } from "..";
import { AddressBookQuery } from "./AddressBookQuery";
import { createAddressBook } from "./createAddressBook";
import { executeUpdate } from "./executeUpdate";

interface CreateAddressBookCommand {
container: string;
name: string;
}

interface ModuleConfig {
store: IndexedFormula;
fetcher: Fetcher;
updater: UpdateManager;
}

export class ContactsModuleRdfLib implements ContactsModule {
private fetcher: Fetcher;
private store: IndexedFormula;
private updater: UpdateManager;
private readonly fetcher: Fetcher;
private readonly store: IndexedFormula;
private readonly updater: UpdateManager;

constructor(config: ModuleConfig) {
this.store = graph();
this.fetcher = new Fetcher(this.store, { fetch: config.fetch });
this.updater = new UpdateManager(this.store);
this.store = config.store;
this.fetcher = config.fetcher;
this.updater = config.updater;
}

async readAddressBook(uri: string): Promise<AddressBook> {
Expand Down Expand Up @@ -58,16 +58,7 @@ export class ContactsModuleRdfLib implements ContactsModule {

async createAddressBook({ container, name }: CreateAddressBookCommand) {
const operation = createAddressBook(container, name);
await this.updater.update(operation.deletions, operation.insertions);
operation.filesToCreate.map((file) => {
this.createEmptyTurtleFile(file.uri);
});
await executeUpdate(this.fetcher, this.updater, operation);
return operation.uri;
}

private async createEmptyTurtleFile(uri: string) {
await this.fetcher.webOperation("PUT", uri, {
contentType: "text/turtle",
});
}
}
10 changes: 9 additions & 1 deletion contacts/src/rdflib/create-address-book.integration.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import {
expectPatchRequest,
expectPutEmptyTurtleFile,
} from "../test-support/expectRequests";
import { Fetcher, graph, UpdateManager } from "rdflib";

jest.mock("uuid");

Expand All @@ -17,9 +18,16 @@ describe("create address book", () => {
"c1eabcdb-fd69-4889-9ab2-f06be49d27d3",
);

const contacts = new ContactsModuleRdfLib({
const store = graph();
const fetcher = new Fetcher(store, {
fetch: authenticatedFetch,
});
const updater = new UpdateManager(store);
const contacts = new ContactsModuleRdfLib({
store,
fetcher,
updater,
});

mockNotFound(
authenticatedFetch,
Expand Down
19 changes: 19 additions & 0 deletions contacts/src/rdflib/executeUpdate.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
import { Fetcher, UpdateManager } from "rdflib";
import { UpdateOperation } from "./createAddressBook";

export async function executeUpdate(
fetcher: Fetcher,
updater: UpdateManager,
operation: UpdateOperation,
) {
await updater.update(operation.deletions, operation.insertions);
operation.filesToCreate.map((file) => {
createEmptyTurtleFile(fetcher, file.uri);
});
}

function createEmptyTurtleFile(fetcher: Fetcher, uri: string) {
return fetcher.webOperation("PUT", uri, {
contentType: "text/turtle",
});
}
Original file line number Diff line number Diff line change
@@ -1,15 +1,14 @@
import { ContactsModuleRdfLib } from "./ContactsModuleRdfLib";
import { mockTurtleResponse } from "../test-support/mockResponses";
import { Fetcher, graph, UpdateManager } from "rdflib";

describe("read existing address book", () => {
it("empty address book returns the title and uri but no contacts and groups", async () => {
const uri = "https://pod.test/alice/contacts/index.ttl#this";

const authenticatedFetch = jest.fn();

const contacts = new ContactsModuleRdfLib({
fetch: authenticatedFetch,
});
const contacts = setupModule(authenticatedFetch);

mockTurtleResponse(
authenticatedFetch,
Expand Down Expand Up @@ -52,9 +51,7 @@ describe("read existing address book", () => {

const authenticatedFetch = jest.fn();

const contacts = new ContactsModuleRdfLib({
fetch: authenticatedFetch,
});
const contacts = setupModule(authenticatedFetch);

mockTurtleResponse(
authenticatedFetch,
Expand Down Expand Up @@ -118,9 +115,7 @@ describe("read existing address book", () => {

const authenticatedFetch = jest.fn();

const contacts = new ContactsModuleRdfLib({
fetch: authenticatedFetch,
});
const contacts = setupModule(authenticatedFetch);

mockTurtleResponse(
authenticatedFetch,
Expand Down Expand Up @@ -187,3 +182,17 @@ describe("read existing address book", () => {
]);
});
});

function setupModule(authenticatedFetch: jest.Mock) {
const store = graph();
const fetcher = new Fetcher(store, {
fetch: authenticatedFetch,
});
const updater = new UpdateManager(store);
const contacts = new ContactsModuleRdfLib({
store,
fetcher,
updater,
});
return contacts;
}

0 comments on commit d3a726d

Please sign in to comment.