add basic test db infra
Boom, now we can also run a clean MySQL test db on each test that wants it :) the test I wrote as a sample is currently marked `it.skip` because it's not passing yet!
This commit is contained in:
parent
68b7beae1b
commit
07691a4e6b
7 changed files with 214 additions and 9 deletions
|
@ -44,7 +44,7 @@
|
||||||
"mysql-dev": "mysql --host=localhost --user=impress_2020_dev --password=impress_2020_dev --database=impress_2020_dev",
|
"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",
|
"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",
|
"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": "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",
|
"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",
|
"build-cached-data": "node -r dotenv/config scripts/build-cached-data.js",
|
||||||
|
|
|
@ -133,4 +133,4 @@ UNLOCK TABLES;
|
||||||
/*!40101 SET COLLATION_CONNECTION=@OLD_COLLATION_CONNECTION */;
|
/*!40101 SET COLLATION_CONNECTION=@OLD_COLLATION_CONNECTION */;
|
||||||
/*!40111 SET SQL_NOTES=@OLD_SQL_NOTES */;
|
/*!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
|
||||||
|
|
|
@ -43,6 +43,30 @@ CREATE TABLE `items` (
|
||||||
KEY `objects_last_spidered` (`last_spidered`)
|
KEY `objects_last_spidered` (`last_spidered`)
|
||||||
) ENGINE=InnoDB AUTO_INCREMENT=81718 DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci;
|
) ENGINE=InnoDB AUTO_INCREMENT=81718 DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci;
|
||||||
/*!40101 SET character_set_client = @saved_cs_client */;
|
/*!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 */;
|
/*!40103 SET TIME_ZONE=@OLD_TIME_ZONE */;
|
||||||
|
|
||||||
/*!40101 SET SQL_MODE=@OLD_SQL_MODE */;
|
/*!40101 SET SQL_MODE=@OLD_SQL_MODE */;
|
||||||
|
@ -53,4 +77,4 @@ CREATE TABLE `items` (
|
||||||
/*!40101 SET COLLATION_CONNECTION=@OLD_COLLATION_CONNECTION */;
|
/*!40101 SET COLLATION_CONNECTION=@OLD_COLLATION_CONNECTION */;
|
||||||
/*!40111 SET SQL_NOTES=@OLD_SQL_NOTES */;
|
/*!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
|
||||||
|
|
|
@ -3,8 +3,10 @@ const mysql = require("mysql2");
|
||||||
let globalDb;
|
let globalDb;
|
||||||
|
|
||||||
async function connectToDb({
|
async function connectToDb({
|
||||||
|
host = "impress.openneo.net",
|
||||||
user = process.env["IMPRESS_MYSQL_USER"],
|
user = process.env["IMPRESS_MYSQL_USER"],
|
||||||
password = process.env["IMPRESS_MYSQL_PASSWORD"],
|
password = process.env["IMPRESS_MYSQL_PASSWORD"],
|
||||||
|
database = "openneo_impress",
|
||||||
} = {}) {
|
} = {}) {
|
||||||
if (globalDb) {
|
if (globalDb) {
|
||||||
return globalDb;
|
return globalDb;
|
||||||
|
@ -12,10 +14,10 @@ async function connectToDb({
|
||||||
|
|
||||||
globalDb = mysql
|
globalDb = mysql
|
||||||
.createConnection({
|
.createConnection({
|
||||||
host: "impress.openneo.net",
|
host,
|
||||||
user,
|
user,
|
||||||
password,
|
password,
|
||||||
database: "openneo_impress",
|
database,
|
||||||
multipleStatements: true,
|
multipleStatements: true,
|
||||||
})
|
})
|
||||||
// We upgrade to promises here, instead of using the mysql2/promise import,
|
// We upgrade to promises here, instead of using the mysql2/promise import,
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
const gql = require("graphql-tag");
|
const gql = require("graphql-tag");
|
||||||
const { query, getDbCalls } = require("./setup.js");
|
const { query, getDbCalls, clearDbCalls, useTestDb } = require("./setup.js");
|
||||||
|
|
||||||
describe("Pet", () => {
|
describe("Pet", () => {
|
||||||
it("looks up a pet", async () => {
|
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();
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
|
|
@ -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",
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
}
|
||||||
|
`;
|
||||||
|
|
|
@ -1,3 +1,6 @@
|
||||||
|
const fs = require("fs");
|
||||||
|
const path = require("path");
|
||||||
|
|
||||||
const { ApolloServer } = require("apollo-server");
|
const { ApolloServer } = require("apollo-server");
|
||||||
const { createTestClient } = require("apollo-server-testing");
|
const { createTestClient } = require("apollo-server-testing");
|
||||||
const { AuthenticationClient } = require("auth0");
|
const { AuthenticationClient } = require("auth0");
|
||||||
|
@ -29,9 +32,40 @@ const { query } = createTestClient(
|
||||||
jest.mock("../db");
|
jest.mock("../db");
|
||||||
let dbExecuteFn;
|
let dbExecuteFn;
|
||||||
let db;
|
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(() => {
|
beforeAll(() => {
|
||||||
connectToDb.mockImplementation(async (...args) => {
|
connectToDb.mockImplementation(async () => {
|
||||||
db = await actualConnectToDb(...args);
|
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");
|
dbExecuteFn = jest.spyOn(db, "execute");
|
||||||
return db;
|
return db;
|
||||||
});
|
});
|
||||||
|
@ -41,6 +75,7 @@ beforeEach(() => {
|
||||||
if (dbExecuteFn) {
|
if (dbExecuteFn) {
|
||||||
dbExecuteFn.mockClear();
|
dbExecuteFn.mockClear();
|
||||||
}
|
}
|
||||||
|
dbEnvironment = "production";
|
||||||
});
|
});
|
||||||
afterAll(() => {
|
afterAll(() => {
|
||||||
if (db) {
|
if (db) {
|
||||||
|
@ -48,6 +83,14 @@ afterAll(() => {
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
const getDbCalls = () => (dbExecuteFn ? dbExecuteFn.mock.calls : []);
|
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() {
|
async function logInAsTestUser() {
|
||||||
const auth0 = new AuthenticationClient({
|
const auth0 = new AuthenticationClient({
|
||||||
|
@ -83,4 +126,10 @@ expect.extend({
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
module.exports = { query, getDbCalls, logInAsTestUser };
|
module.exports = {
|
||||||
|
query,
|
||||||
|
getDbCalls,
|
||||||
|
clearDbCalls,
|
||||||
|
useTestDb,
|
||||||
|
logInAsTestUser,
|
||||||
|
};
|
||||||
|
|
Loading…
Reference in a new issue