diff --git a/package.json b/package.json index cc87f93..473301c 100644 --- a/package.json +++ b/package.json @@ -44,7 +44,7 @@ "mysql-dev": "mysql --host=localhost --user=impress_2020_dev --password=impress_2020_dev --database=impress_2020_dev", "mysql-admin": "mysql --host=impress.openneo.net --user=matchu --password --database=openneo_impress", "mysqldump": "mysqldump --host=impress.openneo.net --user=$(dotenv -p IMPRESS_MYSQL_USER) --password=$(dotenv -p IMPRESS_MYSQL_PASSWORD) --column-statistics=0", - "download-mysql-schema": "yarn --silent mysqldump openneo_impress species species_translations colors color_translations > scripts/setup-mysql-dev-constants.sql && yarn --silent mysqldump --no-data openneo_impress items > scripts/setup-mysql-dev-schema.sql", + "download-mysql-schema": "yarn --silent mysqldump openneo_impress species species_translations colors color_translations > scripts/setup-mysql-dev-constants.sql && yarn --silent mysqldump --no-data openneo_impress items item_translations > scripts/setup-mysql-dev-schema.sql", "setup-mysql": "yarn mysql-admin < scripts/setup-mysql.sql", "setup-mysql-dev": "yarn mysql-dev < scripts/setup-mysql-dev-constants.sql && yarn mysql-dev < scripts/setup-mysql-dev-schema.sql", "build-cached-data": "node -r dotenv/config scripts/build-cached-data.js", diff --git a/scripts/setup-mysql-dev-constants.sql b/scripts/setup-mysql-dev-constants.sql index 31cd483..94a9806 100644 --- a/scripts/setup-mysql-dev-constants.sql +++ b/scripts/setup-mysql-dev-constants.sql @@ -133,4 +133,4 @@ UNLOCK TABLES; /*!40101 SET COLLATION_CONNECTION=@OLD_COLLATION_CONNECTION */; /*!40111 SET SQL_NOTES=@OLD_SQL_NOTES */; --- Dump completed on 2020-09-18 5:22:41 +-- Dump completed on 2020-09-18 5:47:49 diff --git a/scripts/setup-mysql-dev-schema.sql b/scripts/setup-mysql-dev-schema.sql index 1fdfe61..ed94ff3 100644 --- a/scripts/setup-mysql-dev-schema.sql +++ b/scripts/setup-mysql-dev-schema.sql @@ -43,6 +43,30 @@ CREATE TABLE `items` ( KEY `objects_last_spidered` (`last_spidered`) ) ENGINE=InnoDB AUTO_INCREMENT=81718 DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci; /*!40101 SET character_set_client = @saved_cs_client */; + +-- +-- Table structure for table `item_translations` +-- + +DROP TABLE IF EXISTS `item_translations`; +/*!40101 SET @saved_cs_client = @@character_set_client */; +/*!50503 SET character_set_client = utf8mb4 */; +CREATE TABLE `item_translations` ( + `id` int(11) NOT NULL AUTO_INCREMENT, + `item_id` int(11) DEFAULT NULL, + `locale` varchar(255) DEFAULT NULL, + `name` varchar(255) DEFAULT NULL, + `description` text, + `rarity` varchar(255) DEFAULT NULL, + `created_at` datetime DEFAULT NULL, + `updated_at` datetime DEFAULT NULL, + PRIMARY KEY (`id`), + KEY `index_item_translations_on_item_id` (`item_id`), + KEY `index_item_translations_on_locale` (`locale`), + KEY `index_item_translations_name` (`name`), + KEY `index_item_translations_on_item_id_and_locale` (`item_id`,`locale`) +) ENGINE=InnoDB AUTO_INCREMENT=215758 DEFAULT CHARSET=latin1; +/*!40101 SET character_set_client = @saved_cs_client */; /*!40103 SET TIME_ZONE=@OLD_TIME_ZONE */; /*!40101 SET SQL_MODE=@OLD_SQL_MODE */; @@ -53,4 +77,4 @@ CREATE TABLE `items` ( /*!40101 SET COLLATION_CONNECTION=@OLD_COLLATION_CONNECTION */; /*!40111 SET SQL_NOTES=@OLD_SQL_NOTES */; --- Dump completed on 2020-09-18 5:22:43 +-- Dump completed on 2020-09-18 5:47:52 diff --git a/src/server/db.js b/src/server/db.js index 4a77e22..a981f87 100644 --- a/src/server/db.js +++ b/src/server/db.js @@ -3,8 +3,10 @@ const mysql = require("mysql2"); let globalDb; async function connectToDb({ + host = "impress.openneo.net", user = process.env["IMPRESS_MYSQL_USER"], password = process.env["IMPRESS_MYSQL_PASSWORD"], + database = "openneo_impress", } = {}) { if (globalDb) { return globalDb; @@ -12,10 +14,10 @@ async function connectToDb({ globalDb = mysql .createConnection({ - host: "impress.openneo.net", + host, user, password, - database: "openneo_impress", + database, multipleStatements: true, }) // We upgrade to promises here, instead of using the mysql2/promise import, diff --git a/src/server/query-tests/Pet.test.js b/src/server/query-tests/Pet.test.js index 2b51d73..cea327d 100644 --- a/src/server/query-tests/Pet.test.js +++ b/src/server/query-tests/Pet.test.js @@ -1,5 +1,5 @@ const gql = require("graphql-tag"); -const { query, getDbCalls } = require("./setup.js"); +const { query, getDbCalls, clearDbCalls, useTestDb } = require("./setup.js"); describe("Pet", () => { it("looks up a pet", async () => { @@ -50,4 +50,61 @@ describe("Pet", () => { ] `); }); + + it.skip("models new item data", async () => { + useTestDb(); + + const res = await query({ + query: gql` + query { + petOnNeopetsDotCom(petName: "roopal27") { + items { + id + name + description + thumbnailUrl + rarityIndex + isNc + } + } + } + `, + }); + + expect(res).toHaveNoErrors(); + expect(res.data).toMatchSnapshot(); + expect(getDbCalls()).toMatchInlineSnapshot(`Array []`); + + clearDbCalls(); + + const res2 = await query({ + query: gql` + query { + items( + ids: [ + "37229" + "37375" + "38911" + "38912" + "38913" + "43014" + "43397" + "48313" + ] + ) { + id + name + description + thumbnailUrl + rarityIndex + isNc + } + } + `, + }); + + expect(res2).toHaveNoErrors(); + expect(res2.data).toMatchSnapshot(); + expect(getDbCalls()).toMatchInlineSnapshot(); + }); }); diff --git a/src/server/query-tests/__snapshots__/Pet.test.js.snap b/src/server/query-tests/__snapshots__/Pet.test.js.snap index 27fcffa..4647fa6 100644 --- a/src/server/query-tests/__snapshots__/Pet.test.js.snap +++ b/src/server/query-tests/__snapshots__/Pet.test.js.snap @@ -81,3 +81,76 @@ Object { }, } `; + +exports[`Pet models new item data 1`] = ` +Object { + "petOnNeopetsDotCom": Object { + "items": Array [ + Object { + "description": "What does this ball actually do?", + "id": "37229", + "isNc": false, + "name": "Magic Ball Table", + "rarityIndex": 101, + "thumbnailUrl": "http://images.neopets.com/items/gif_magicball_table.gif", + }, + Object { + "description": "Dont forget to wish upon a star.", + "id": "37375", + "isNc": false, + "name": "Moon and Stars Background", + "rarityIndex": 75, + "thumbnailUrl": "http://images.neopets.com/items/bg_moonstars.gif", + }, + Object { + "description": "Hide your face and hair so no one can recognise you.", + "id": "38911", + "isNc": false, + "name": "Zafara Agent Hood", + "rarityIndex": 92, + "thumbnailUrl": "http://images.neopets.com/items/clo_zafara_agent_hood.gif", + }, + Object { + "description": "This robe is great for being stealthy.", + "id": "38912", + "isNc": false, + "name": "Zafara Agent Robe", + "rarityIndex": 90, + "thumbnailUrl": "http://images.neopets.com/items/clo_zafara_agent_robe.gif", + }, + Object { + "description": "Dont leave any trace that you were there with these gloves.", + "id": "38913", + "isNc": false, + "name": "Zafara Agent Gloves", + "rarityIndex": 88, + "thumbnailUrl": "http://images.neopets.com/items/clo_zafara_agent_gloves.gif", + }, + Object { + "description": "These leaves almost look magical with their gentle glow.", + "id": "43014", + "isNc": false, + "name": "Green Leaf String Lights", + "rarityIndex": 80, + "thumbnailUrl": "http://images.neopets.com/items/toy_stringlight_illleaf.gif", + }, + Object { + "description": "This jewelled staff shines with a magical light.", + "id": "43397", + "isNc": true, + "name": "Jewelled Staff", + "rarityIndex": 500, + "thumbnailUrl": "http://images.neopets.com/items/mall_staff_jewelled.gif", + }, + Object { + "description": "Even the announcers of the Altador Cup celebrate. This was given out by the Advent Calendar in Y11.", + "id": "48313", + "isNc": false, + "name": "Altador Cup Brooch", + "rarityIndex": 101, + "thumbnailUrl": "http://images.neopets.com/items/clo_altcuplogo_brooch.gif", + }, + ], + }, +} +`; diff --git a/src/server/query-tests/setup.js b/src/server/query-tests/setup.js index f518bfc..4e60ddf 100644 --- a/src/server/query-tests/setup.js +++ b/src/server/query-tests/setup.js @@ -1,3 +1,6 @@ +const fs = require("fs"); +const path = require("path"); + const { ApolloServer } = require("apollo-server"); const { createTestClient } = require("apollo-server-testing"); const { AuthenticationClient } = require("auth0"); @@ -29,9 +32,40 @@ const { query } = createTestClient( jest.mock("../db"); let dbExecuteFn; let db; +let dbEnvironment = "production"; +const dbSetupScripts = [ + fs + .readFileSync( + path.join(__dirname, "../../../scripts/setup-mysql-dev-constants.sql") + ) + .toString(), + fs + .readFileSync( + path.join(__dirname, "../../../scripts/setup-mysql-dev-schema.sql") + ) + .toString(), +]; beforeAll(() => { - connectToDb.mockImplementation(async (...args) => { - db = await actualConnectToDb(...args); + connectToDb.mockImplementation(async () => { + let options; + + if (dbEnvironment === "test") { + options = { + host: "localhost", + user: "impress_2020_test", + password: "impress_2020_test", + database: "impress_2020_test", + }; + } + + db = await actualConnectToDb(options); + + if (dbEnvironment === "test") { + for (const script of dbSetupScripts) { + await db.query(script); + } + } + dbExecuteFn = jest.spyOn(db, "execute"); return db; }); @@ -41,6 +75,7 @@ beforeEach(() => { if (dbExecuteFn) { dbExecuteFn.mockClear(); } + dbEnvironment = "production"; }); afterAll(() => { if (db) { @@ -48,6 +83,14 @@ afterAll(() => { } }); const getDbCalls = () => (dbExecuteFn ? dbExecuteFn.mock.calls : []); +const clearDbCalls = () => dbExecuteFn?.mockClear(); + +function useTestDb() { + if (db) { + throw new Error(`can't call useTestDb() if db mock already exists`); + } + dbEnvironment = "test"; +} async function logInAsTestUser() { const auth0 = new AuthenticationClient({ @@ -83,4 +126,10 @@ expect.extend({ }, }); -module.exports = { query, getDbCalls, logInAsTestUser }; +module.exports = { + query, + getDbCalls, + clearDbCalls, + useTestDb, + logInAsTestUser, +};