Skip to content

Commit

Permalink
feat(platforms): adds twitter abstraction tests (passportxyz#657)
Browse files Browse the repository at this point in the history
* feat(platforms): adds twitter abstraction tests

* feat(platforms): modifies import structure
  • Loading branch information
farque65 authored Oct 27, 2022
1 parent 6db76da commit a0c0e1b
Show file tree
Hide file tree
Showing 9 changed files with 485 additions and 20 deletions.
6 changes: 3 additions & 3 deletions iam/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -40,15 +40,15 @@ import { Providers } from "./utils/providers";
// ---- Identity Providers
import { SimpleProvider } from "./providers/simple";
import { GoogleProvider } from "./providers/google";
// import { TwitterProvider } from "./providers/twitter";

import {
TwitterAuthProvider,
TwitterFollowerGT100Provider,
TwitterFollowerGT5000Provider,
TwitterFollowerGT500Provider,
TwitterFollowerGTE1000Provider,
TwitterFollowerGT5000Provider,
TwitterTweetGT10Provider,
} from "@gitcoin/passport-platforms";
} from "@gitcoin/passport-platforms/dist/commonjs/src/Twitter";

import { PohProvider } from "./providers/poh";
import { POAPProvider } from "./providers/poap";
Expand Down
103 changes: 103 additions & 0 deletions platforms/__tests__/Twitter/twitter.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,103 @@
// ---- Test subject
import TwitterProvider from "../../src/Twitter/Providers/TwitterAuthProvider";

import { RequestPayload } from "@gitcoin/passport-types";
import { auth } from "twitter-api-sdk";
import {
deleteClient,
getClient,
requestFindMyUser,
TwitterFindMyUserResponse,
} from "../../src/Twitter/procedures/twitterOauth";

jest.mock("../../src/Twitter/procedures/twitterOauth", () => ({
getClient: jest.fn(),
deleteClient: jest.fn(),
requestFindMyUser: jest.fn(),
}));

const MOCK_TWITTER_OAUTH_CLIENT = {} as auth.OAuth2User;

const MOCK_TWITTER_USER: TwitterFindMyUserResponse = {
id: "123",
name: "Userguy McTesterson",
username: "DpoppDev",
};

const sessionKey = "twitter-myOAuthSession";
const code = "ABC123_ACCESSCODE";

beforeEach(() => {
jest.clearAllMocks();
(getClient as jest.Mock).mockReturnValue(MOCK_TWITTER_OAUTH_CLIENT);
});

describe("Attempt verification", function () {
it("handles valid verification attempt", async () => {
(requestFindMyUser as jest.Mock).mockResolvedValue(MOCK_TWITTER_USER);

const twitter = new TwitterProvider();
const verifiedPayload = await twitter.verify({
proofs: {
sessionKey,
code,
},
} as unknown as RequestPayload);

expect(getClient).toBeCalledWith(sessionKey);
expect(requestFindMyUser).toBeCalledWith(MOCK_TWITTER_OAUTH_CLIENT, code);
expect(deleteClient).toBeCalledWith(sessionKey);
expect(verifiedPayload).toEqual({
valid: true,
record: {
username: MOCK_TWITTER_USER.username,
},
});
});

it("should return invalid payload when unable to retrieve twitter oauth client", async () => {
(getClient as jest.Mock).mockResolvedValueOnce(undefined);
(requestFindMyUser as jest.Mock).mockResolvedValueOnce((client: TwitterFindMyUserResponse | undefined) => {
return client ? MOCK_TWITTER_USER : {};
});

const twitter = new TwitterProvider();
const verifiedPayload = await twitter.verify({
proofs: {
sessionKey,
code,
},
} as unknown as RequestPayload);
expect(verifiedPayload).toMatchObject({ valid: false });
});

it("should return invalid payload when there is no username in requestFindMyUser response", async () => {
(requestFindMyUser as jest.Mock).mockResolvedValue({ username: undefined });

const twitter = new TwitterProvider();

const verifiedPayload = await twitter.verify({
proofs: {
sessionKey,
code,
},
} as unknown as RequestPayload);

expect(verifiedPayload).toMatchObject({ valid: false });
});

it("should return invalid payload when requestFindMyUser throws", async () => {
(requestFindMyUser as jest.Mock).mockRejectedValue("unauthorized");

const twitter = new TwitterProvider();

const verifiedPayload = await twitter.verify({
proofs: {
sessionKey,
code,
},
} as unknown as RequestPayload);

expect(verifiedPayload).toMatchObject({ valid: false });
});
});
233 changes: 233 additions & 0 deletions platforms/__tests__/Twitter/twitterFollower.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,233 @@
// ---- Test subject
import {
TwitterFollowerGT100Provider,
TwitterFollowerGT500Provider,
TwitterFollowerGTE1000Provider,
TwitterFollowerGT5000Provider,
} from "../../src/Twitter/Providers/TwitterFollowerProvider";

import { RequestPayload } from "@gitcoin/passport-types";
import { auth } from "twitter-api-sdk";
import {
deleteClient,
getClient,
getFollowerCount,
TwitterFollowerResponse,
} from "../../src/Twitter/procedures/twitterOauth";

jest.mock("../../src/Twitter/procedures/twitterOauth", () => ({
getClient: jest.fn(),
deleteClient: jest.fn(),
getFollowerCount: jest.fn(),
}));

const MOCK_TWITTER_OAUTH_CLIENT = {} as auth.OAuth2User;

const MOCK_TWITTER_USER: TwitterFollowerResponse = {
username: "DpoppDev",
followerCount: 200,
};

const sessionKey = "twitter-myOAuthSession";
const code = "ABC123_ACCESSCODE";

beforeEach(() => {
jest.clearAllMocks();
(getClient as jest.Mock).mockReturnValue(MOCK_TWITTER_OAUTH_CLIENT);
});

describe("Attempt verification", function () {
it("handles valid verification attempt", async () => {
(getFollowerCount as jest.Mock).mockResolvedValue(MOCK_TWITTER_USER);

const twitter = new TwitterFollowerGT100Provider();
const verifiedPayload = await twitter.verify({
proofs: {
sessionKey,
code,
},
} as unknown as RequestPayload);

expect(getClient).toBeCalledWith(sessionKey);
expect(getFollowerCount).toBeCalledWith(MOCK_TWITTER_OAUTH_CLIENT, code);
expect(deleteClient).toBeCalledWith(sessionKey);
expect(verifiedPayload).toEqual({
valid: true,
record: {
username: "DpoppDev",
followerCount: "gt100",
},
});
});

it("should return invalid payload when unable to retrieve twitter oauth client", async () => {
(getClient as jest.Mock).mockReturnValue(undefined);
(getFollowerCount as jest.Mock).mockImplementationOnce(async (client) => {
return Promise.resolve(client ? MOCK_TWITTER_USER : {});
});

const twitter = new TwitterFollowerGT100Provider();

const verifiedPayload = await twitter.verify({
proofs: {
sessionKey,
code,
},
} as unknown as RequestPayload);

expect(verifiedPayload).toMatchObject({ valid: false });
});

it("should return invalid payload when there is no username in requestFindMyUser response", async () => {
(getFollowerCount as jest.Mock).mockResolvedValue({ username: undefined });

const twitter = new TwitterFollowerGT100Provider();

const verifiedPayload = await twitter.verify({
proofs: {
sessionKey,
code,
},
} as unknown as RequestPayload);

expect(verifiedPayload).toMatchObject({ valid: false });
});

it("should return invalid payload when requestFindMyUser throws", async () => {
(getFollowerCount as jest.Mock).mockRejectedValue("unauthorized");

const twitter = new TwitterFollowerGT100Provider();

const verifiedPayload = await twitter.verify({
proofs: {
sessionKey,
code,
},
} as unknown as RequestPayload);

expect(verifiedPayload).toMatchObject({ valid: false });
});

describe("Check invalid cases for follower ranges", function () {
it("Expected Greater than 100 and Follower Count is 50", async () => {
(getFollowerCount as jest.Mock).mockResolvedValue({ followerCount: 50 });

const twitter = new TwitterFollowerGT100Provider();

const verifiedPayload = await twitter.verify({
proofs: {
sessionKey,
code,
},
} as unknown as RequestPayload);

expect(verifiedPayload).toMatchObject({ valid: false });
});

it("Expected Greater than 500 and Follower Count is 150", async () => {
(getFollowerCount as jest.Mock).mockResolvedValue({ followerCount: 150 });

const twitter = new TwitterFollowerGT500Provider();

const verifiedPayload = await twitter.verify({
proofs: {
sessionKey,
code,
},
} as unknown as RequestPayload);

expect(verifiedPayload).toMatchObject({ valid: false });
});

it("Expected Greater than or equal to 1000 and Follower Count is 900", async () => {
(getFollowerCount as jest.Mock).mockResolvedValue({ followerCount: 900 });

const twitter = new TwitterFollowerGTE1000Provider();

const verifiedPayload = await twitter.verify({
proofs: {
sessionKey,
code,
},
} as unknown as RequestPayload);

expect(verifiedPayload).toMatchObject({ valid: false });
});

it("Expected Greater than 5000 and Follower Count is 2500", async () => {
(getFollowerCount as jest.Mock).mockResolvedValue({ followerCount: 2500 });

const twitter = new TwitterFollowerGT5000Provider();

const verifiedPayload = await twitter.verify({
proofs: {
sessionKey,
code,
},
} as unknown as RequestPayload);

expect(verifiedPayload).toMatchObject({ valid: false });
});
});
describe("Check valid cases for follower ranges", function () {
it("Expected Greater than 100 and Follower Count is 150", async () => {
(getFollowerCount as jest.Mock).mockResolvedValue({ followerCount: 150 });

const twitter = new TwitterFollowerGT100Provider();

const verifiedPayload = await twitter.verify({
proofs: {
sessionKey,
code,
},
} as unknown as RequestPayload);

expect(verifiedPayload).toMatchObject({ valid: true });
});

it("Expected Greater than 500 and Follower Count is 700", async () => {
(getFollowerCount as jest.Mock).mockResolvedValue({ followerCount: 700 });

const twitter = new TwitterFollowerGT500Provider();

const verifiedPayload = await twitter.verify({
proofs: {
sessionKey,
code,
},
} as unknown as RequestPayload);

expect(verifiedPayload).toMatchObject({ valid: true });
});

it("Expected Greater than or equal to 1000 and Follower Count is 1500", async () => {
(getFollowerCount as jest.Mock).mockResolvedValue({ followerCount: 1500 });

const twitter = new TwitterFollowerGTE1000Provider();

const verifiedPayload = await twitter.verify({
proofs: {
sessionKey,
code,
},
} as unknown as RequestPayload);

expect(verifiedPayload).toMatchObject({ valid: true });
});

it("Expected Greater than 5000 and Follower Count is 7500", async () => {
(getFollowerCount as jest.Mock).mockResolvedValue({ followerCount: 7500 });

const twitter = new TwitterFollowerGT5000Provider();

const verifiedPayload = await twitter.verify({
proofs: {
sessionKey,
code,
},
} as unknown as RequestPayload);

expect(verifiedPayload).toMatchObject({ valid: true });
});
});
});
Loading

0 comments on commit a0c0e1b

Please sign in to comment.