Skip to content

Commit

Permalink
Merge pull request #1004 from lfglabs-dev/feat/add-braavos-mobile
Browse files Browse the repository at this point in the history
feat: add braavos mobile
  • Loading branch information
Marchand-Nicolas authored Dec 27, 2024
2 parents 3f81544 + efe262d commit dece1c4
Show file tree
Hide file tree
Showing 11 changed files with 235 additions and 58 deletions.
58 changes: 33 additions & 25 deletions app/analytics/page.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -17,12 +17,12 @@ export default function Page() {
const { address } = useAccount();
const [loading, setLoading] = useState<boolean>(true);

const [quests, setQuests] = useState<QuestList> ({} as QuestList);
const [quests, setQuests] = useState<QuestList>({} as QuestList);

const fetchQuests = useCallback(async () => {
try {
setLoading(true);
const res = await getQuests() || {};
const res = (await getQuests()) || {};
setQuests(res);
setLoading(false);
} catch (error) {
Expand All @@ -39,34 +39,42 @@ export default function Page() {
<div className={styles.backButton}>
<BackButton onClick={() => router.back()} />
</div>
<Typography type={TEXT_TYPE.H1} color="transparent" className={styles.title}>Quest Analytics</Typography>
<Typography
type={TEXT_TYPE.H1}
color="transparent"
className={styles.title}
>
Quest Analytics
</Typography>
<div className={styles.card_container}>
{loading ? (
<FeaturedQuestSkeleton />
) : (
(Object.keys(quests) as (keyof typeof quests)[]).map((categoryName: keyof typeof quests) => {
const categoryValue = quests[categoryName];
if (Array.isArray(categoryValue)) {
return categoryValue.map((quest: QuestDocument) => {
return (
<Quest
key={quest.id}
title={quest.title_card}
onClick={() => router.push(`/analytics/${quest.id}`)}
imgSrc={quest.img_card}
issuer={{
name: quest.issuer,
logoFavicon: quest.logo,
}}
reward={quest.rewards_title}
id={quest.id}
expired={false}
/>
);
});
(Object.keys(quests) as (keyof typeof quests)[]).map(
(categoryName: keyof typeof quests) => {
const categoryValue = quests[categoryName];
if (Array.isArray(categoryValue)) {
return categoryValue.map((quest: QuestDocument) => {
return (
<Quest
key={quest.id}
title={quest.title_card}
onClick={() => router.push(`/analytics/${quest.id}`)}
imgSrc={quest.img_card}
issuer={{
name: quest.issuer,
logoFavicon: quest.logo,
}}
reward={quest.rewards_title}
id={quest.id}
expired={false}
/>
);
});
}
return null;
}
return null;
})
)
)}
</div>
</div>
Expand Down
6 changes: 1 addition & 5 deletions app/provider.tsx
Original file line number Diff line number Diff line change
@@ -1,20 +1,16 @@
"use client";

import React from "react";
import { InjectedConnector } from "starknetkit/injected";
import { WebWalletConnector } from "starknetkit/webwallet";
import { ArgentMobileConnector } from "starknetkit/argentMobile";
import { Chain, mainnet, sepolia } from "@starknet-react/chains";
import {
Connector,
StarknetConfig,
jsonRpcProvider,
} from "@starknet-react/core";
import { StarknetIdJsProvider } from "@context/StarknetIdJsProvider";
import { ThemeProvider, createTheme } from "@mui/material";
import { ThemeProvider } from "@mui/material";
import { QuestsContextProvider } from "@context/QuestsProvider";
import { getCurrentNetwork } from "@utils/network";
import { constants } from "starknet";
import { PostHogProvider } from "posthog-js/react";
import posthog from "posthog-js";
import { NotificationProvider } from "@context/NotificationProvider";
Expand Down
1 change: 0 additions & 1 deletion context/QuestsProvider.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -138,7 +138,6 @@ export const QuestsContextProvider = ({
!quest.expired
)
: undefined;

setFeaturedQuest(
lastBoostedQuest ||
notExpired[Math.floor(Math.random() * notExpired.length)]
Expand Down
9 changes: 5 additions & 4 deletions jest.config.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
module.exports = {
testEnvironment: "node",
transform: {
"\\.[jt]sx?$": "ts-jest",
"^.+\\.(js|jsx|ts|tsx)$": ["babel-jest", { presets: ["next/babel"] }],
},
setupFilesAfterEnv: ["./jest.setup.js"],
moduleNameMapper: {
Expand All @@ -16,9 +16,10 @@ module.exports = {
coverageThreshold: {
"./utils/": {
branches: 75,
functions: 90,
functions: 80,
lines: 90,
statements: -10,
statements: -23,
},
},
};
transformIgnorePatterns: ["node_modules/(?!(@starknet-react|@starknetkit)/)"],
};
5 changes: 3 additions & 2 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,8 @@
"chart.js": "^4.3.0",
"dayjs": "^1.11.11",
"eslint-config-next": "^14.0.1",
"get-starknet-core": "^3.2.0",
"get-starknet": "^3.3.3",
"get-starknet-core": "^3.3.3",
"jotai": "^2.5.0",
"jwt-decode": "^4.0.0",
"lottie-react": "^2.4.0",
Expand All @@ -51,7 +52,7 @@
"recharts": "^2.12.2",
"starknet": "^6.11.0",
"starknetid.js": "^4.0.1",
"starknetkit": "^2.3.3",
"starknetkit": "^2.6.1",
"three": "^0.155.0",
"twitter-api-sdk": "^1.2.1"
},
Expand Down
Binary file added public/visuals/braavosMobile.webp
Binary file not shown.
86 changes: 86 additions & 0 deletions tests/utils/braavosMobile.test.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,86 @@
import { mainnet, sepolia } from "@starknet-react/chains";
import {
ConnectorNotConnectedError,
UserNotConnectedError,
} from "@starknet-react/core";
import { BraavosMobileConnector, getBraavosMobile } from "@utils/braavosMobile";

describe("BraavosMobileConnector class", () => {
let connector;

beforeEach(() => {
connector = new BraavosMobileConnector();
});

describe("id getter", () => {
it("should return 'braavosMobile'", () => {
expect(connector.id).toBe("braavosMobile");
});
});

describe("icon getter", () => {
it("should return the same icon for light and dark modes", () => {
expect(connector.icon.light).toBeDefined();
expect(connector.icon.dark).toBeDefined();
expect(connector.icon.light).toBe(connector.icon.dark);
});
});

describe("name getter", () => {
it("should return 'Braavos (mobile)'", () => {
expect(connector.name).toBe("Braavos (mobile)");
});
});

describe("available method", () => {
it("should return true", () => {
expect(connector.available()).toBe(true);
});
});

describe("wallet getter", () => {
it("should throw a ConnectorNotConnectedError", () => {
expect(() => connector.wallet).toThrow(ConnectorNotConnectedError);
});
});

describe("disconnect method", () => {
it("should throw a UserNotConnectedError", () => {
expect(() => connector.disconnect()).toThrow(UserNotConnectedError);
});
});

describe("account method", () => {
it("should throw a ConnectorNotConnectedError", () => {
expect(() => connector.account()).toThrow(ConnectorNotConnectedError);
});
});

describe("chainId method", () => {
it("should return sepolia.id when NEXT_PUBLIC_IS_TESTNET is 'true'", async () => {
process.env.NEXT_PUBLIC_IS_TESTNET = "true";
const result = await connector.chainId();
expect(result).toBe(sepolia.id);
});

it("should return mainnet.id when NEXT_PUBLIC_IS_TESTNET is not 'true'", async () => {
process.env.NEXT_PUBLIC_IS_TESTNET = "false";
const result = await connector.chainId();
expect(result).toBe(mainnet.id);
});
});

describe("ready method", () => {
it("should return true as a Promise", async () => {
const result = await connector.ready();
expect(result).toBe(true);
});
});
});

describe("getBraavosMobile function", () => {
it("should return an instance of BraavosMobileConnector", () => {
const instance = getBraavosMobile();
expect(instance).toBeInstanceOf(BraavosMobileConnector);
});
});
27 changes: 16 additions & 11 deletions tests/utils/domainService.test.js
Original file line number Diff line number Diff line change
@@ -1,23 +1,26 @@
import { getDomainFromAddress } from '@utils/domainService';
import { getDomainFromAddress } from "@utils/domainService";

const API_URL = process.env.NEXT_PUBLIC_STARKNET_ID_API_LINK;

describe("getDomainFromAddress function", () => {
it("should return a valid domain for a valid address", async () => {
const validAddress = "0x061b6c0a78f9edf13cea17b50719f3344533fadd470b8cb29c2b4318014f52d3";
it("should return a valid domain for a valid address", async () => {
const validAddress =
"0x061b6c0a78f9edf13cea17b50719f3344533fadd470b8cb29c2b4318014f52d3";
const expectedDomain = "fricoben.stark";

// Mocking the fetch function to return a predefined response
const mockResponse = { domain: expectedDomain };
const fetchMock = jest.fn().mockResolvedValue({
json: jest.fn().mockResolvedValue(mockResponse),
json: jest.fn().mockResolvedValue(mockResponse),
});
(fetch as jest.Mock) = fetchMock;
fetch = fetchMock;

const domain = await getDomainFromAddress(validAddress);

expect(domain).toBe(expectedDomain);
expect(fetchMock).toHaveBeenCalledWith(`${API_URL}/addr_to_domain?addr=${validAddress}`);
expect(fetchMock).toHaveBeenCalledWith(
`${API_URL}/addr_to_domain?addr=${validAddress}`
);
});

it("should return an empty string for an invalid address", async () => {
Expand All @@ -27,13 +30,15 @@ it("should return a valid domain for a valid address", async () => {
// Mocking the fetch function to simulate an error
const mockResponse = { domain: expectedDomain };
const fetchMock = jest.fn().mockResolvedValue({
json: jest.fn().mockResolvedValue(mockResponse),
});
(fetch as jest.Mock) = fetchMock;
json: jest.fn().mockResolvedValue(mockResponse),
});
fetch = fetchMock;

const domain = await getDomainFromAddress(invalidAddress);

expect(domain).toBe("");
expect(fetchMock).toHaveBeenCalledWith(`${API_URL}/addr_to_domain?addr=${invalidAddress}`);
expect(fetchMock).toHaveBeenCalledWith(
`${API_URL}/addr_to_domain?addr=${invalidAddress}`
);
});
});
});
Loading

0 comments on commit dece1c4

Please sign in to comment.