Skip to content

Commit

Permalink
mock api endpoints added for testcases
Browse files Browse the repository at this point in the history
  • Loading branch information
darsan-in committed Nov 29, 2024
1 parent f26510e commit a8fd9fc
Show file tree
Hide file tree
Showing 7 changed files with 602 additions and 19 deletions.
32 changes: 20 additions & 12 deletions lib/gindex.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import { type Hawk } from "./core";
import {
GoogleIndexResponseOptions,
GoogleIndexStatusCode,
GoogleJobMediaIndexingPayload,
LastStateType,
RanStatusFileStructure,
SitemapMeta,
Expand Down Expand Up @@ -39,22 +40,23 @@ export default class GoogleIndexing {
updatedRoute: string,
): Promise<GoogleIndexResponseOptions> {
try {
const postData = {
const postData: GoogleJobMediaIndexingPayload = {
url: updatedRoute,
type: "URL_UPDATED",
};

const response = await fetch(
"https://indexing.googleapis.com/v3/urlNotifications:publish",
{
method: "POST",
headers: {
"Content-Type": "application/json",
Authorization: `Bearer ${accessToken}`,
},
body: JSON.stringify(postData),
const endpoint = process.env.isdev
? "http://localhost:8080/google-jobmedia-indexing"
: "https://indexing.googleapis.com/v3/urlNotifications:publish";

const response = await fetch(endpoint, {
method: "POST",
headers: {
"Content-Type": "application/json",
Authorization: `Bearer ${accessToken}`,
},
);
body: JSON.stringify(postData),
});

const responseBody = await response.json();

Expand Down Expand Up @@ -201,7 +203,13 @@ export default class GoogleIndexing {
siteUrl,
)}/sitemaps/${encodeURIComponent(sitemapURL)}`;

const response = await fetch(apiUrl, {
const endpoint = process.env.isdev
? `http://localhost:8080/webmaster/${encodeURIComponent(
siteUrl,
)}/sitemaps/${encodeURIComponent(sitemapURL)}`
: apiUrl;

const response = await fetch(endpoint, {
method: "PUT",
headers: {
Authorization: `Bearer ${accessToken}`,
Expand Down
12 changes: 8 additions & 4 deletions lib/indexnow.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import { type Hawk } from "./core";
import {
constants,
ftpCredentialOptions,
IndexNowPayload,
RanStatusFileStructure,
} from "./types";

Expand Down Expand Up @@ -138,20 +139,23 @@ export default class IndexNow {
updatedRoutes: string[],
secretkey: string,
): Promise<number> {
const data = JSON.stringify({
const data: IndexNowPayload = {
host: this.#domainName,
key: secretkey,
keyLocation: `https://${this.#domainName}/${secretkey}.txt`,
urlList: updatedRoutes,
});
};

const endpoint = process.env.isdev
? "http://localhost:8080/indexnow"
: "https://api.indexnow.org/IndexNow";
try {
const response = await fetch("https://api.indexnow.org/IndexNow", {
const response = await fetch(endpoint, {
method: "POST",
headers: {
"Content-Type": "application/json; charset=utf-8",
},
body: data,
body: JSON.stringify(data),
});

return response.status; // Return the HTTP status code
Expand Down
12 changes: 12 additions & 0 deletions lib/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -81,3 +81,15 @@ export interface SecretObjectType {
user: string;
pass: string;
}

export interface IndexNowPayload {
host: string;
key: string;
keyLocation: string;
urlList: string[];
}

export interface GoogleJobMediaIndexingPayload {
url: string;
type: "URL_UPDATED";
}
2 changes: 2 additions & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -74,6 +74,7 @@
"@babel/core": "7.26.0",
"@babel/preset-env": "7.26.0",
"@babel/preset-typescript": "7.26.0",
"@types/express": "^5.0.0",
"@types/jest": "29.5.14",
"@types/jstoxml": "2.0.4",
"@types/luxon": "3.4.2",
Expand All @@ -83,6 +84,7 @@
"babel-jest": "29.7.0",
"commander": "^12.1.0",
"eslint": "^9.15.0",
"express": "^4.21.1",
"fast-xml-parser": "^4.5.0",
"jest": "29.7.0",
"ncp": "^2.0.0",
Expand Down
24 changes: 24 additions & 0 deletions test/mock-api/app.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
import express from "express";
import router from "./routes";

const app = express();

app.use(express.json());
app.use(express.urlencoded({ extended: false }));

app.use("/", router);

// error handler
app.use(function (err: any, _req: any, res: any, _next: () => any) {
// set locals, only providing error in development
res.locals.message = err.message;
res.locals.error = err;

// render the error page
res.status(err.status || 500);
res.json({ error: err });
});

const port = 8080;
app.set("port", port);
app.listen(port, () => console.log("Server ready on port:", port));
117 changes: 117 additions & 0 deletions test/mock-api/routes.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,117 @@
import express from "express";
import {
GoogleJobMediaIndexingPayload,
IndexNowPayload,
} from "../../lib/types";
const router = express.Router();

//PUT
router.put(
"/webmaster/*",
function (req: any, res: any, _next: () => void) {
try {
let [hostname, _, sitemapUrl] = req.url.split("/").slice(-3);
hostname = decodeURIComponent(hostname);
sitemapUrl = decodeURIComponent(sitemapUrl);

const isSameOrginMap = hostname
? sitemapUrl
? hostname.includes(new URL(sitemapUrl).hostname)
: false
: false;

const authtoken = req.headers["authorization"];
const validAuthToken = authtoken && authtoken.length > 150;

if (validAuthToken && isSameOrginMap) {
res.status(200).json({ msg: "Success" });
} else {
res.status(400).json({ msg: "Bad request" });
}
} catch (err) {
res.status(500).json({ msg: err });
}
},
);

//POST
router.post(
"/google-jobmedia-indexing",
function (req: any, res: any, _next: () => void) {
try {
const payload: GoogleJobMediaIndexingPayload = req.body;

const { url, type } = payload;

const validPayload = url
? new URL(url)?.hostname
? type
? true
: false
: false
: false;

const validType = type === "URL_UPDATED";

const authtoken = req.headers["authorization"];
const validAuthToken = authtoken && authtoken.length > 150;

if (validPayload && validType && validAuthToken) {
res.status(200).json({ msg: "Good request" });
} else {
res.status(400).json({ msg: "Required field missing" });
}
} catch (err) {
res.status(500).json({ error: err });
}
},
);

//POST
router.post("/indexnow", function (req: any, res: any, _next: () => void) {
try {
const payload: IndexNowPayload = req.body;

console.log("Received Payload:", payload);

const { host, key, keyLocation, urlList } = payload;

const isNotFound: string | false = !host
? "Host"
: !key
? "Key"
: !keyLocation
? "Key location"
: !urlList
? "Urlist"
: false;

const keyIsValid = key.length >= 32;

const keyLocationIsValid =
(new URL(keyLocation).pathname || false) && //check if its valid url and has path
(new URL(host).hostname || false) && //check if its valid url
keyLocation.includes(host); // check if host intersect with keylocation

const allUrlsAreValid = Array.isArray(urlList) //check if urlist is valid array
? urlList.every((url) => new URL(url).hostname || false) //check if all given url are valid
: false;

if (
!isNotFound &&
keyIsValid &&
keyLocationIsValid &&
allUrlsAreValid
) {
res.status(200).json({ msg: "Good request" });
} else {
res.status(400).json({
msg: "Required field missing or urlList must be array or failed at validation",
});
}
} catch (err) {
res.status(500).json({ error: err });
}
});

export default router;
Loading

0 comments on commit a8fd9fc

Please sign in to comment.