From 5e8982aaef0818e4972feec2c5e71b4b56449a8c Mon Sep 17 00:00:00 2001 From: Cyrine-BA <95730706+Cyrine-BA@users.noreply.github.com> Date: Thu, 16 Nov 2023 22:24:25 -0500 Subject: [PATCH 1/2] Added tests --- src/fetchCurrentTemperature.test.ts | 13 ++++++++ src/fetchGeoCoord.test.ts | 42 +++++++++++++++++++----- src/main.ts | 33 +++++++++++-------- src/universityWeather.test.ts | 51 +++++++++++++++++++++++++++-- src/universityWeather.ts | 30 ++++++++++------- 5 files changed, 133 insertions(+), 36 deletions(-) diff --git a/src/fetchCurrentTemperature.test.ts b/src/fetchCurrentTemperature.test.ts index 1d5eb06..a01df17 100644 --- a/src/fetchCurrentTemperature.test.ts +++ b/src/fetchCurrentTemperature.test.ts @@ -13,4 +13,17 @@ describe("fetchCurrentTemperature", () => { assert(result.temperature_2m.every(x => typeof x === "number")); // Assert each element in that time is a number }); }); + + it("Promise rejects when given wrong latitude and longitude numbers", () => { + return expect(fetchCurrentTemperature({lat:100, lon: 200})).rejects.toThrow(); + }); + + it("returns the right array length", () => { + const promise = fetchCurrentTemperature({ lat: 0, lon: 0 }); + + return promise.then(result => { + assert (result.time.length === result.temperature_2m.length); //check array length + }); + }); + }); diff --git a/src/fetchGeoCoord.test.ts b/src/fetchGeoCoord.test.ts index 5b861ed..4fb50dc 100644 --- a/src/fetchGeoCoord.test.ts +++ b/src/fetchGeoCoord.test.ts @@ -1,15 +1,39 @@ import assert from "assert"; import { fetchGeoCoord } from "./fetchGeoCoord.js"; + describe("fetchGeoCoord", () => { - it("follows type specification", () => { - const promise = fetchGeoCoord("University of Massachusetts Amherst"); - - return promise.then(result => { - assert(typeof result === "object"); // Assert the result is an object - assert(typeof result.lon === "number"); // Assert that the lon value is a number - assert(typeof result.lat === "number"); // Assert that the lat value is a number - assert(Object.keys(result).length === 2); // Assert there are only two keys in the object - }); + it("follows type specification", () => { + const promise = fetchGeoCoord("University of Massachusetts Amherst"); + + return promise.then(result => { + assert(typeof result === "object"); // Assert the result is an object + assert(typeof result.lon === "number"); // Assert that the lon value is a number + assert(typeof result.lat === "number"); // Assert that the lat value is a number + assert(Object.keys(result).length === 2); // Assert there are only two keys in the object }); + }); + + it("throws an error for an invalid location", () => { + const promise = fetchGeoCoord("XYZ"); + return promise.catch(error => {assert(error === ("No results found for query."))}) + }) + + it("gives the correct coordinates for University of Massachusetts Amherst", () => { + const promise = fetchGeoCoord("University of Massachusetts Amherst"); + + return promise.then(result => { + assert(result.lat === 42.3869382); + assert(result.lon === -72.52991477067445); + }) + }) + + it("gives the correct coordinates for Amherst College", () => { + const promise = fetchGeoCoord("Amherst College"); + + return promise.then(result => { + assert(result.lat === 42.3703768); + assert(result.lon === -72.5160691823344); + }) + }) }); diff --git a/src/main.ts b/src/main.ts index 0072529..139627e 100644 --- a/src/main.ts +++ b/src/main.ts @@ -1,16 +1,23 @@ -import { fetchUMassWeather, fetchUCalWeather, fetchUniversityWeather, AverageTemperatureResults } from "./universityWeather.js"; +import { fetchUMassWeather, fetchUCalWeather, fetchUniversityWeather, AverageTemperatureResults} from "./universityWeather.js"; +import { fetchUniversities } from "./fetchUniversities.js"; +import { fetchGeoCoord } from "./fetchGeoCoord.js"; +import { fetchCurrentTemperature } from "./fetchCurrentTemperature.js"; + + +// fetchUMassWeather().then(results => console.log(results)).catch(error => console.error(error)); +// fetchUCalWeather().then(results => console.log(results)).catch(error => console.log(error)); + +// const randomCollegeSearch = (universityQuery: string) : Promise => { +// return fetchUniversityWeather(universityQuery).then(res => { +// console.log(`\n${universityQuery} search:`); +// return res; +// }); +// } + +// randomCollegeSearch("Boston College").then(console.log); +// randomCollegeSearch("Smith College").then(console.log); +// randomCollegeSearch("Harvard University").then(console.log); +// randomCollegeSearch("test").then(console.log).catch(error => console.error("Expected", error)); -fetchUMassWeather().then(results => console.log(results)).catch(error => console.error(error)); -fetchUCalWeather().then(results => console.log(results)).catch(error => console.log(error)); -const randomCollegeSearch = (universityQuery: string) : Promise => { - return fetchUniversityWeather(universityQuery).then(res => { - console.log(`\n${universityQuery} search:`); - return res; - }); -} -randomCollegeSearch("Boston College").then(console.log); -randomCollegeSearch("Smith College").then(console.log); -randomCollegeSearch("Harvard University").then(console.log); -randomCollegeSearch("test").then(console.log).catch(error => console.error("Expected", error)); diff --git a/src/universityWeather.test.ts b/src/universityWeather.test.ts index 7453198..d9e9181 100644 --- a/src/universityWeather.test.ts +++ b/src/universityWeather.test.ts @@ -1,11 +1,38 @@ import assert from "assert"; -import { fetchUCalWeather, fetchUMassWeather } from "./universityWeather.js"; +import { fetchUCalWeather, fetchUMassWeather, fetchUniversityWeather } from "./universityWeather.js"; // 1000ms -const SECOND = 1000; +const SECOND = 5000; // 30 second timeout jest.setTimeout(30 * SECOND); + +describe("fetchUniversityWeather", () => { + it("returns an error when entered an empty query", () => { + return expect(fetchUniversityWeather("No results found for query.")).rejects.toThrow(); + }); + + it("works 1 university", () => { + const promise = fetchUniversityWeather("University of Connecticut"); + + return promise.then(result => { + expect(result.totalAverage).toEqual(result['University of Connecticut']); + }); + }); + + it("works with 2 universities", () => { + const promise = fetchUniversityWeather("Aachen"); + + return promise.then(result => { + const x1 = result['Rheinisch Westfälische Technische Hochschule Aachen']; + const x2 = result['Fachhochschule Aachen']; + expect(result.totalAverage).toEqual((x1+x2)/2); + }); + }) +}) + + + describe("fetchUCalWeather", () => { it("follows type specification", () => { const promise = fetchUCalWeather(); @@ -20,6 +47,13 @@ describe("fetchUCalWeather", () => { it(`should fetch weather data for UMass universities`, () => { return fetchUMassWeather().then(result => { expect(result).toHaveProperty(`totalAverage`); + [ + 'University of Massachusetts Boston', + 'University of Massachusetts at Dartmouth', + 'University of Massachusetts at Lowell', + 'University of Massachusetts at Amherst' + ].forEach(name => expect(result).toHaveProperty(name)); + }); }); }); @@ -38,6 +72,19 @@ describe("fetchUMassWeather", () => { it(`should fetch weather data for UCal Universities`, () => { return fetchUCalWeather().then(result => { expect(result).toHaveProperty(`totalAverage`); + [ + 'University of California, Merced', + 'University of California, Irvine', + 'University of California, Berkeley', + 'University of California, Davis', + 'University of California, Los Angeles', + 'University of California, Office of the President', + 'University of California, Santa Cruz', + 'University of California, Santa Barbara', + 'University of California, San Diego', + 'University of California, San Francisco', + 'University of California, Riverside' + ].forEach(name => expect(result).toHaveProperty(name)); }); }); }); diff --git a/src/universityWeather.ts b/src/universityWeather.ts index 8935924..09f3141 100644 --- a/src/universityWeather.ts +++ b/src/universityWeather.ts @@ -15,7 +15,8 @@ export function fetchUniversityWeather( if (universityNames.length === 0) throw new Error("No results found for query."); const transformedNames = transformName ? universityNames.map(transformName) : universityNames; const geoCoordPromises = transformedNames.map(name => fetchGeoCoord(name)); - return Promise.all(geoCoordPromises).then(geoCoords => { + return Promise.all(geoCoordPromises) + .then(geoCoords => { const temperaturePromises = geoCoords.map((coord, index) => fetchCurrentTemperature(coord).then(temperature => { const averageTemp = temperature.temperature_2m.reduce((a, b) => a + b, 0) / temperature.temperature_2m.length; return { @@ -23,25 +24,30 @@ export function fetchUniversityWeather( averageTemp }; })); - return Promise.all(temperaturePromises).then(temperatures => { - let totalAverage = 0; - const results: AverageTemperatureResults = { totalAverage: 0 }; - temperatures.forEach(temp => { - totalAverage += temp.averageTemp; - results[temp.name] = temp.averageTemp; - }); - results.totalAverage = totalAverage / temperatures.length; - return results; + return Promise.all(temperaturePromises) + }) + .then(temperatures => { + let totalAverage = 0; + const results: AverageTemperatureResults = { totalAverage: 0 }; + temperatures.forEach(temp => { + totalAverage += temp.averageTemp; + results[temp.name] = temp.averageTemp; }); + results.totalAverage = totalAverage / temperatures.length; + return results; + }); }) } +function transformName (name: string): string { + return name.replace(/ at|,|-/g, ' '); +} + export function fetchUMassWeather(): Promise { - const transformName = (name: string): string => name.replace(` at `, ` `); return fetchUniversityWeather(`University of Massachusetts`, transformName); } export function fetchUCalWeather(): Promise { - return fetchUniversityWeather(`University of California`); + return fetchUniversityWeather(`University of California`, transformName); } From 845d7e2de771114992971b6c03784632d7a876d6 Mon Sep 17 00:00:00 2001 From: Cyrine-BA <95730706+Cyrine-BA@users.noreply.github.com> Date: Mon, 20 Nov 2023 16:38:52 -0500 Subject: [PATCH 2/2] working example --- src/main.ts | 114 +++++++++++++++++++++++++++++++++++++++++++--------- 1 file changed, 94 insertions(+), 20 deletions(-) diff --git a/src/main.ts b/src/main.ts index 139627e..8ca537b 100644 --- a/src/main.ts +++ b/src/main.ts @@ -1,23 +1,97 @@ -import { fetchUMassWeather, fetchUCalWeather, fetchUniversityWeather, AverageTemperatureResults} from "./universityWeather.js"; -import { fetchUniversities } from "./fetchUniversities.js"; -import { fetchGeoCoord } from "./fetchGeoCoord.js"; -import { fetchCurrentTemperature } from "./fetchCurrentTemperature.js"; - - -// fetchUMassWeather().then(results => console.log(results)).catch(error => console.error(error)); -// fetchUCalWeather().then(results => console.log(results)).catch(error => console.log(error)); - -// const randomCollegeSearch = (universityQuery: string) : Promise => { -// return fetchUniversityWeather(universityQuery).then(res => { -// console.log(`\n${universityQuery} search:`); -// return res; -// }); -// } - -// randomCollegeSearch("Boston College").then(console.log); -// randomCollegeSearch("Smith College").then(console.log); -// randomCollegeSearch("Harvard University").then(console.log); -// randomCollegeSearch("test").then(console.log).catch(error => console.error("Expected", error)); +import fetch from "../include/fetch.js"; +import path from "path"; + +// TODO - Now its your turn to make the working example! :) +/* +authorInfo takes in an author name and gets the data from the link. +It uses this information to get the author id. +Using this author id we can then access all the author specific information. +Also using the author id we can get the works of the author +This is what authorWorks does. +*/ + +interface docs{ + key: string; + type: string; + name: string; + alternateNames: string[]; + birthDate: string; + topWork: string; + workCount: string; + topSubjects: string; + version: string; +} + +interface author{ + numFound: number; + start: number; + numFoundExact: boolean; + docs: docs[] +} + +interface Book { + type: { + key: string; + }; + title: string; + authors: { + type: { + key: string; + }; + author: { + key: string; + }; + }[]; + covers: number[]; + key: string; + latest_revision: number; + revision: number; + created: { + type: string; + value: string; + }; + last_modified: { + type: string; + value: string; + }; +} + + +export function authorInfo(name:string){ + const authorName = name.replace(". ", " "); + const baseURL = "https://220.maxkuechen.com/fetch/noCache/?url=https://openlibrary.org"; + const apiURL = `${baseURL}/search/authors.json?q=${encodeURIComponent(authorName)}`; + + fetch(apiURL) + .then(result => result.ok ? result.json() : Promise.reject(new Error(`Error in response: ${result.statusText}`))) + .then ((response: author) => { + return response.numFoundExact && Array.isArray(response.docs) && response.docs.length>0 + ? Promise.resolve(response.docs[0].key) + : Promise.reject(new Error("No results found for the given author.")); + }) + .then((Id:string) => {console.log ("Author's ID: " ,Id) ; return fetch (`https://220.maxkuechen.com/fetch/noCache/?url=https://openlibrary.org/authors/${encodeURIComponent(Id)}.json`)}) + .then (res => res.ok ? res.json() : Promise.reject(new Error(`Error in response: ${res.statusText}`))) + .then (info =>console.log("Author's information: ", info.bio)) + .catch(error => console.log("Invalid", error)); +} + +export function authorWorks(authorID:string, numWorks: number) { + const apiURL = `https://220.maxkuechen.com/fetch/noCache/?url=https://openlibrary.org/authors/${encodeURIComponent(authorID)}/works.json?limit=${encodeURIComponent(numWorks)}`; + console.log(apiURL); + + fetch(apiURL) + .then(result => result.ok ? result.json() : Promise.reject(new Error("Error in response: ${result.statusText}"))) + .then(response => { + console.log("Author Works:"); + response.entries.forEach ((bk: Book) => console.log(bk.title) ); + }) + .catch(error => console.log("Invalid") + error); +} + +authorInfo("J K Rowling"); +authorWorks("OL23919A", 10); + +