Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

1599 optimize requests #1653

Merged
merged 5 commits into from
Aug 29, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
156 changes: 72 additions & 84 deletions app/__tests__/context/ceramicContext.test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -228,27 +228,24 @@ describe("CeramicContextProvider syncs stamp state with ceramic", () => {
(PassportDatabase as jest.Mock).mockImplementationOnce(() => {
return {
...passportDbMocks,
addStamps: addStampsMock,
getPassport: jest
.fn()
.mockImplementationOnce(async () => {
return {
passport: {
stamps: [],
},
errorDetails: {},
status: "Success",
};
})
.mockImplementationOnce(async () => {
return {
passport: {
stamps,
},
errorDetails: {},
status: "Success",
};
}),
addStamps: addStampsMock.mockImplementationOnce(async () => {
return {
passport: {
stamps,
},
errorDetails: {},
status: "Success",
};
}),
getPassport: jest.fn().mockImplementationOnce(async () => {
return {
passport: {
stamps: [],
},
errorDetails: {},
status: "Success",
};
}),
setStamps: setStampMock,
};
});
Expand Down Expand Up @@ -288,27 +285,24 @@ describe("CeramicContextProvider syncs stamp state with ceramic", () => {
(PassportDatabase as jest.Mock).mockImplementationOnce(() => {
return {
...passportDbMocks,
deleteStamps: deleteStampsMock,
getPassport: jest
.fn()
.mockImplementationOnce(async () => {
return {
passport: {
stamps,
},
errorDetails: {},
status: "Success",
};
})
.mockImplementationOnce(async () => {
return {
passport: {
stamps: [],
},
errorDetails: {},
status: "Success",
};
}),
deleteStamps: deleteStampsMock.mockImplementationOnce(async () => {
return {
passport: {
stamps: [],
},
errorDetails: {},
status: "Success",
};
}),
getPassport: jest.fn().mockImplementationOnce(async () => {
return {
passport: {
stamps: [],
},
errorDetails: {},
status: "Success",
};
}),
};
});
(CeramicDatabase as jest.Mock).mockImplementationOnce(() => {
Expand Down Expand Up @@ -346,27 +340,24 @@ describe("CeramicContextProvider syncs stamp state with ceramic", () => {
(PassportDatabase as jest.Mock).mockImplementationOnce(() => {
return {
...passportDbMocks,
patchStamps: patchStampsMock,
getPassport: jest
.fn()
.mockImplementationOnce(async () => {
return {
passport: {
stamps: [],
},
errorDetails: {},
status: "Success",
};
})
.mockImplementationOnce(async () => {
return {
passport: {
stamps: added,
},
errorDetails: {},
status: "Success",
};
}),
patchStamps: patchStampsMock.mockImplementationOnce(async () => {
return {
passport: {
stamps: added,
},
errorDetails: {},
status: "Success",
};
}),
getPassport: jest.fn().mockImplementationOnce(async () => {
return {
passport: {
stamps: added,
},
errorDetails: {},
status: "Success",
};
}),
};
});

Expand Down Expand Up @@ -400,27 +391,24 @@ describe("CeramicContextProvider syncs stamp state with ceramic", () => {
(PassportDatabase as jest.Mock).mockImplementationOnce(() => {
return {
...passportDbMocks,
patchStamps: patchStampsMock,
getPassport: jest
.fn()
.mockImplementationOnce(async () => {
return {
passport: {
stamps: [],
},
errorDetails: {},
status: "Success",
};
})
.mockImplementationOnce(async () => {
return {
passport: {
stamps,
},
errorDetails: {},
status: "Success",
};
}),
patchStamps: patchStampsMock.mockImplementationOnce(async () => {
return {
passport: {
stamps,
},
errorDetails: {},
status: "Success",
};
}),
getPassport: jest.fn().mockImplementationOnce(async () => {
return {
passport: {
stamps,
},
errorDetails: {},
status: "Success",
};
}),
};
});

Expand Down
66 changes: 42 additions & 24 deletions app/context/ceramicContext.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { createContext, useContext, useEffect, useMemo, useState, useRef } from "react";
import { createContext, useContext, useEffect, useState, useRef, useCallback } from "react";
import {
Passport,
PassportLoadResponse,
Expand Down Expand Up @@ -383,7 +383,8 @@ export const CeramicContextProvider = ({ children }: { children: any }) => {
case "connected": {
if (dbAccessTokenStatus === "failed") {
setIsLoadingPassport(IsLoadingPassportState.FailedToConnect);
} else if (dbAccessToken && address) {
break;
} else if (dbAccessToken && address && !database) {
// Ceramic Network Connection
const ceramicClientInstance = new CeramicDatabase(
viewerConnection.selfID.did,
Expand Down Expand Up @@ -415,13 +416,13 @@ export const CeramicContextProvider = ({ children }: { children: any }) => {
default:
break;
}
}, [viewerConnection.status, address, dbAccessToken, dbAccessTokenStatus]);
}, [viewerConnection, address, dbAccessToken, dbAccessTokenStatus]);

useEffect(() => {
if (database && ceramicClient) {
if (database) {
fetchPassport(database, false, true);
}
}, [database, ceramicClient]);
}, [database]);

const passportLoadSuccess = (
database: CeramicDatabase | PassportDatabase,
Expand Down Expand Up @@ -457,17 +458,16 @@ export const CeramicContextProvider = ({ children }: { children: any }) => {
}
};

const fetchPassport = async (
const handlePassportUpdate = async (
passportResponse: PassportLoadResponse,
database: CeramicDatabase | PassportDatabase,
skipLoadingState?: boolean,
isInitialLoad?: boolean
): Promise<Passport | undefined> => {
if (!skipLoadingState) setIsLoadingPassport(IsLoadingPassportState.Loading);

// fetch, clean and set the new Passport state
const { status, errorDetails, passport } = await database.getPassport();
) => {
let passportToReturn: Passport | undefined = undefined;

const { status, errorDetails, passport } = passportResponse;

switch (status) {
case "Success":
passportToReturn = passportLoadSuccess(database, passport, skipLoadingState);
Expand All @@ -493,6 +493,19 @@ export const CeramicContextProvider = ({ children }: { children: any }) => {
return passportToReturn;
};

const fetchPassport = async (
database: CeramicDatabase | PassportDatabase,
skipLoadingState?: boolean,
isInitialLoad?: boolean
): Promise<Passport | undefined> => {
if (!skipLoadingState) setIsLoadingPassport(IsLoadingPassportState.Loading);

// fetch, clean and set the new Passport state
const getResponse = await database.getPassport();

return await handlePassportUpdate(getResponse, database, skipLoadingState, isInitialLoad);
};

const handleCheckRefreshPassport = async (): Promise<boolean> => {
let success = true;
if (ceramicClient && passportLoadResponse) {
Expand Down Expand Up @@ -600,10 +613,14 @@ export const CeramicContextProvider = ({ children }: { children: any }) => {
const handleAddStamps = async (stamps: Stamp[]): Promise<void> => {
try {
if (database) {
await database.addStamps(stamps);
const newPassport = await fetchPassport(database, true);
if (ceramicClient && newPassport) {
ceramicClient.setStamps(newPassport.stamps).catch((e) => console.log("error setting ceramic stamps", e));
const addResponse = await database.addStamps(stamps);

handlePassportUpdate(addResponse, database);

if (ceramicClient && addResponse.passport) {
ceramicClient
.setStamps(addResponse.passport.stamps)
.catch((e) => console.log("error setting ceramic stamps", e));
}
if (dbAccessToken) {
refreshScore(address, dbAccessToken);
Expand All @@ -618,10 +635,10 @@ export const CeramicContextProvider = ({ children }: { children: any }) => {
const handlePatchStamps = async (stampPatches: StampPatch[]): Promise<void> => {
try {
if (database) {
await database.patchStamps(stampPatches);
const newPassport = await fetchPassport(database, true);
const patchResponse = await database.patchStamps(stampPatches);
handlePassportUpdate(patchResponse, database);

if (ceramicClient && newPassport) {
if (ceramicClient && patchResponse.passport) {
(async () => {
try {
const deleteProviderIds = stampPatches
Expand All @@ -630,7 +647,7 @@ export const CeramicContextProvider = ({ children }: { children: any }) => {

if (deleteProviderIds.length) await ceramicClient.deleteStampIDs(deleteProviderIds);

await ceramicClient.setStamps(newPassport.stamps);
await ceramicClient.setStamps(patchResponse.passport?.stamps || []);
} catch (e) {
console.log("error patching ceramic stamps", e);
}
Expand All @@ -650,11 +667,12 @@ export const CeramicContextProvider = ({ children }: { children: any }) => {
const handleDeleteStamps = async (providerIds: PROVIDER_ID[]): Promise<void> => {
try {
if (database) {
await database.deleteStamps(providerIds);

const newPassport = await fetchPassport(database, true);
if (ceramicClient && newPassport) {
ceramicClient.setStamps(newPassport.stamps).catch((e) => console.log("error setting ceramic stamps", e));
const deleteResponse = await database.deleteStamps(providerIds);
handlePassportUpdate(deleteResponse, database);
if (ceramicClient && deleteResponse.status === "Success" && deleteResponse.passport?.stamps) {
ceramicClient
.setStamps(deleteResponse.passport.stamps)
.catch((e) => console.log("error setting ceramic stamps", e));
}
if (dbAccessToken) {
refreshScore(address, dbAccessToken);
Expand Down
18 changes: 12 additions & 6 deletions database-client/__tests__/passportScorerClient.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -65,7 +65,8 @@ describe("scorerClient", () => {

it("should log an error when axios.post fails", async () => {
const error = new Error("Request failed");
jest.spyOn(axios, "post").mockImplementation((url: string): Promise<{}> => {
const request = "post";
jest.spyOn(axios, request).mockImplementation((url: string): Promise<{}> => {
return new Promise((_, reject) => {
reject(error);
});
Expand All @@ -75,13 +76,15 @@ describe("scorerClient", () => {

expect(logger.info).toHaveBeenCalledWith(`adding stamp to passportScorer address: ${address}`);
expect(logger.error).toHaveBeenCalledWith(
`Error saving stamp to passportScorer address: ${address}:${error.toString()}`
`[Scorer] Error thrown when making ${request} for passport with did ${address}: Error: Request failed`,
{ error }
);
});

it("should log an error when axios.delete fails", async () => {
const error = new Error("Request failed");
jest.spyOn(axios, "delete").mockImplementation((url: string): Promise<{}> => {
const request = "delete";
jest.spyOn(axios, request).mockImplementation((url: string): Promise<{}> => {
return new Promise((_, reject) => {
reject(error);
});
Expand All @@ -94,7 +97,8 @@ describe("scorerClient", () => {
`deleting stamp from passportScorer for ${providerIds.join(", ")} on ${address}`
);
expect(logger.error).toHaveBeenCalledWith(
`Error deleting stamp from passportScorer for ${providerIds.join(", ")} on ${address}: Error: Request failed`
`[Scorer] Error thrown when making ${request} for passport with did ${address}: Error: Request failed`,
{ error }
);
});

Expand Down Expand Up @@ -132,7 +136,8 @@ describe("scorerClient", () => {

it("should log an error when axios.patch fails", async () => {
const error = new Error("Request failed");
jest.spyOn(axios, "patch").mockImplementation((url: string): Promise<{}> => {
const request = "patch";
jest.spyOn(axios, request).mockImplementation((url: string): Promise<{}> => {
return new Promise((_, reject) => {
reject(error);
});
Expand All @@ -142,7 +147,8 @@ describe("scorerClient", () => {

expect(logger.info).toHaveBeenCalledWith(`patching stamps in passportScorer for address: ${address}`);
expect(logger.error).toHaveBeenCalledWith(
`Error patching stamps in passportScorer for address: ${address}:${error.toString()}`
`[Scorer] Error thrown when making ${request} for passport with did ${address}: ${error.toString()}`,
{ error }
);
});
});
Loading
Loading