From 2dc961e39fa0b6ab8c249199bcf2c9370be915bf Mon Sep 17 00:00:00 2001 From: Mithi Date: Fri, 30 Oct 2020 11:56:46 +0800 Subject: [PATCH 01/19] FIX: Add db url from .env before migrating (fixes error) --- scripts/run_setup.sh | 1 + 1 file changed, 1 insertion(+) diff --git a/scripts/run_setup.sh b/scripts/run_setup.sh index 3ab337f..aa74d92 100644 --- a/scripts/run_setup.sh +++ b/scripts/run_setup.sh @@ -1,5 +1,6 @@ npm run db:create; npm install; +cp .env.sample .env npm run db:migrate-all; npm run test; psql kingdom_rush_user -h localhost -d kingdom_rush_db --pset=pager -f ./scripts/db_gen_info.sql; From 1dec73dc2cbdc68bbba5c52bff37e612741b0b34 Mon Sep 17 00:00:00 2001 From: Mithi Date: Fri, 30 Oct 2020 11:57:13 +0800 Subject: [PATCH 02/19] docs: Update good first issue --- docs/GOOD_FIRST_ISSUE.md | 56 +++++++++++++++++++++++----------------- 1 file changed, 33 insertions(+), 23 deletions(-) diff --git a/docs/GOOD_FIRST_ISSUE.md b/docs/GOOD_FIRST_ISSUE.md index 14393fc..1ee71a5 100644 --- a/docs/GOOD_FIRST_ISSUE.md +++ b/docs/GOOD_FIRST_ISSUE.md @@ -1,51 +1,55 @@ -# Good First Issue +# Good First Pull Request -The descriptions of the tower abilities are a mess, and it needs your help! +The descriptions of the tower abilities are a mess, and this repository needs your help! You can checkout [Kingdom Rush TD fandom](https://kingdomrushtd.fandom.com/wiki/Category:Towers) for ideas for how to make it better. The current descriptions can be found in the following files: -- [./data/raw/KR/abilities.yml](./data/raw/KR/abilities.yml) -- [./data/raw/KRF/abilities.yml](./data/raw/KRF/abilities.yml) -- [./data/raw/KRO/abilities.yml](./data/raw/KRO/abilities.yml) -- [./data/raw/KRV/abilities/abilities.yml](./data/raw/KRV/abilities/abilities.yml) +- [../data/raw/KR/abilities.yml](../data/raw/KR/abilities.yml) +- [../data/raw/KRF/abilities.yml](../data/raw/KRF/abilities.yml) +- [../data/raw/KRO/abilities.yml](../data/raw/KRO/abilities.yml) +- [../data/raw/KRV/abilities/abilities.yml](../data/raw/KRV/abilities/abilities.yml) ## 1. Setup postgreSQL Make sure you have [postgresql](https://postgresapp.com/) installed and running on port 5432. -## 2. Fork, clone, setup env variables +## 2. Fork and clone -Fork this repository, clone. Rename `.env.sample` to `.env` +Fork this repository and clone. ```bash -git clone https://github.com/mithi/kingdom-rush-graphql.git +git clone https://github.com/YOUR_USER_NAME/kingdom-rush-graphql.git cd kingdom-rush-graphql -mv .env.sample .env ``` -## 3. Install npm packages, setup database - -Running this command, will create the necessary user roles and database. -It will then install the npm packages, run the tests, and -run the migrations to ensure that your default database has the correct schema. -Submit and issue if something goes wrong. +## 3. Set things up ```bash npm run setup ``` +Running the command above will do the following: + +1. Create the necessary user roles and database +2. Setup a `.env` file +3. Install the npm packages +4. Run the tests, and +5. Run the migrations to ensure that your default database has the correct schema. + +Submit and issue if something goes wrong. + ## 4. Update the description Edit any of the following (tower ability) descriptions in any of the following yaml files -- [./data/raw/KR/abilities.yml](./data/raw/KR/abilities.yml) -- [./data/raw/KRF/abilities.yml](./data/raw/KRF/abilities.yml) -- [./data/raw/KRO/abilities.yml](./data/raw/KRO/abilities.yml) -- [./data/raw/KRV/abilities/abilities.yml](./data/raw/KRV/abilities/abilities.yml) +- [../data/raw/KR/abilities.yml](../data/raw/KR/abilities.yml) +- [../data/raw/KRF/abilities.yml](../data/raw/KRF/abilities.yml) +- [../data/raw/KRO/abilities.yml](../data/raw/KRO/abilities.yml) +- [../data/raw/KRV/abilities/abilities.yml](../data/raw/KRV/abilities/abilities.yml) -## 5. Regenerate Data and Cleanup +## 5. Regenerate data and cleanup Run `npm run db:update-data` to update the generated/json, populate your database and update the files in `/generated/csv/` and `/generated/txt/`. @@ -58,9 +62,12 @@ npm run test npm run db:drop ``` -## 6. Commit and PR +You can also try running `npm run start` and `npm run build`, they should produce no error. +You can go try out querying some graphql queries like the ones in [example queries](./EXAMPLE_QUERIES.md). -Congratulations! Looking forward to merging your pull request! +## 6. Commit and submit a pull request + +After committing and pushing upstream, ```bash git checkout -b feat/update-tower-ability-description @@ -69,3 +76,6 @@ git add . git commit -m "Update tower ability description" git push ``` + +Go to your remote fork and create the pull request to this reposity. +Congratulations! Looking forward to merging your pull request! From d0e37863257b7d246eaa5568941021ba3d7f9c3d Mon Sep 17 00:00:00 2001 From: Mithi Date: Fri, 30 Oct 2020 11:57:47 +0800 Subject: [PATCH 03/19] test: Add test for seeding build sequence table --- tests/seed.test.ts | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/tests/seed.test.ts b/tests/seed.test.ts index 8388903..db099ee 100644 --- a/tests/seed.test.ts +++ b/tests/seed.test.ts @@ -7,9 +7,11 @@ import { Ability, AbilityLevel, } from "../src/models/" +import { BuildSequence } from "../src/models/BuildSequence" import populateAttackStats from "../src/seed/AttackStats" import populateBarracksStats from "../src/seed/BarracksStats" import { populateTowers, populateAbilities } from "../src/seed/Tower" +import populateBuildSequence from "../src/seed/BuildSequence" beforeEach(async () => { await createConnection("test") @@ -63,3 +65,14 @@ test("3. After populating abilities and ability levels, they should have the exp expect(abilityCount).toBe(87) expect(abilityLevelCount).toBe(228) }) + +test("4. After populating build sequences, they should have the expected number of entries", async () => { + let buildSequenceCount = await getRepository(BuildSequence, "test").count() + expect(buildSequenceCount).toBe(0) + + await populateTowers({ dbName: "test", verbose: false }) + await populateBuildSequence({ dbName: "test", verbose: false }) + + buildSequenceCount = await getRepository(BuildSequence, "test").count() + expect(buildSequenceCount).toBe(35) +}) From 0e4f4d3189bf4bb36237dd0d410d6d17c9a6b2eb Mon Sep 17 00:00:00 2001 From: Mithi Date: Fri, 30 Oct 2020 13:08:32 +0800 Subject: [PATCH 04/19] Make tower models check more comprehensive --- tests/tower_db.test.ts | 34 +++++++++++++++++++++------------- 1 file changed, 21 insertions(+), 13 deletions(-) diff --git a/tests/tower_db.test.ts b/tests/tower_db.test.ts index d04f42c..76a9ee0 100644 --- a/tests/tower_db.test.ts +++ b/tests/tower_db.test.ts @@ -19,6 +19,13 @@ const getExampleMainStats = (): MainStats => { return mainStats } +const EXAMPLE_TOWER_DATA = { + name: "Militia Barracks", + towerType: TowerType.BARRACKS, + level: TowerLevel.LVL1, + kingdom: TowerKingdom.KR, +} + beforeAll(async () => { await createConnection("test") }) @@ -27,35 +34,30 @@ afterAll(async () => { await getConnection("test").close() }) -test("Store tower and fetch it", async () => { +test("Be able to store, fetch, and remove a tower", async () => { const TOWER_REPO = getRepository(Tower, "test") - const exampleTowerData = { - name: "Militia Barracks", - towerType: TowerType.BARRACKS, - level: TowerLevel.LVL1, - kingdom: TowerKingdom.KR, - } - let retrievedTowers = await TOWER_REPO.find({ where: { - name: exampleTowerData.name, + name: EXAMPLE_TOWER_DATA.name, }, }) expect(retrievedTowers.length).toBe(0) - await TOWER_REPO.insert(exampleTowerData) + await TOWER_REPO.insert(EXAMPLE_TOWER_DATA) + expect(await TOWER_REPO.count()).toBe(1) + retrievedTowers = await TOWER_REPO.find({ where: { - name: exampleTowerData.name, + name: EXAMPLE_TOWER_DATA.name, }, }) expect(retrievedTowers.length).toBe(1) const retrievedTower = retrievedTowers[0] - expect(retrievedTower.name).toBe(exampleTowerData.name) + expect(retrievedTower.name).toBe(EXAMPLE_TOWER_DATA.name) await TOWER_REPO.remove(retrievedTower) expect(await TOWER_REPO.count()).toBe(0) @@ -78,6 +80,8 @@ test("Store a tower and add main stats, deleting the tower would also delete mai expect(retrievedTowers.length).toBe(0) await TOWER_REPO.save(tower) + expect(await TOWER_REPO.count()).toBe(1) + expect(await MAIN_STATS_REPO.count()).toBe(1) retrievedTowers = await TOWER_REPO.find({ where: { @@ -97,7 +101,7 @@ test("Store a tower and add main stats, deleting the tower would also delete mai expect(await MAIN_STATS_REPO.count()).toBe(0) }) -test("Be able to store abilities and ability levels of a tower", async () => { +test("Be able to store abilities and ability levels of a tower, deleting tower would remove ability and ability levels", async () => { const TOWER_REPO = getRepository(Tower, "test") const ABILITY_REPO = getRepository(Ability, "test") const ABILITY_LEVEL_REPO = getRepository(AbilityLevel, "test") @@ -146,6 +150,10 @@ test("Be able to store abilities and ability levels of a tower", async () => { expect(retrievedTower.abilities[0].name).toBe(ability1.name) expect(abilities[0].levels[0].cost).toBe(250) + expect(await TOWER_REPO.count()).toBe(1) + expect(await ABILITY_REPO.count()).toBe(1) + expect(await ABILITY_LEVEL_REPO.count()).toBe(1) + await TOWER_REPO.remove(retrievedTower) expect(await TOWER_REPO.count()).toBe(0) expect(await ABILITY_REPO.count()).toBe(0) From cac655a33a27d035a203c5e05e3c864c654d388f Mon Sep 17 00:00:00 2001 From: Mithi Date: Fri, 30 Oct 2020 13:28:19 +0800 Subject: [PATCH 05/19] Add comment sections for readability in test --- tests/tower_db.test.ts | 56 +++++++++++++++++++++++++++++++++++------- 1 file changed, 47 insertions(+), 9 deletions(-) diff --git a/tests/tower_db.test.ts b/tests/tower_db.test.ts index 76a9ee0..9d47544 100644 --- a/tests/tower_db.test.ts +++ b/tests/tower_db.test.ts @@ -34,9 +34,12 @@ afterAll(async () => { await getConnection("test").close() }) -test("Be able to store, fetch, and remove a tower", async () => { +test("1. Be able to store, fetch, and remove a tower", async () => { const TOWER_REPO = getRepository(Tower, "test") + /******************** + * Our example tower shouldn't exist yet in our empty test database + ********************/ let retrievedTowers = await TOWER_REPO.find({ where: { name: EXAMPLE_TOWER_DATA.name, @@ -45,9 +48,16 @@ test("Be able to store, fetch, and remove a tower", async () => { expect(retrievedTowers.length).toBe(0) + /******************** + * We shoud ne able to successfully insert the tower, + * increasing entry count of table by one + ********************/ await TOWER_REPO.insert(EXAMPLE_TOWER_DATA) expect(await TOWER_REPO.count()).toBe(1) + /******************** + * We should able to find our inserted tower by name + ********************/ retrievedTowers = await TOWER_REPO.find({ where: { name: EXAMPLE_TOWER_DATA.name, @@ -59,11 +69,14 @@ test("Be able to store, fetch, and remove a tower", async () => { const retrievedTower = retrievedTowers[0] expect(retrievedTower.name).toBe(EXAMPLE_TOWER_DATA.name) + /******************** + * We should be able to remove the tower we inserted + ********************/ await TOWER_REPO.remove(retrievedTower) expect(await TOWER_REPO.count()).toBe(0) }) -test("Store a tower and add main stats, deleting the tower would also delete main stats", async () => { +test("2. Store a tower and add main stats deleting the tower would also delete main stats", async () => { const TOWER_REPO = getRepository(Tower, "test") const MAIN_STATS_REPO = getRepository(MainStats, "test") @@ -71,6 +84,10 @@ test("Store a tower and add main stats, deleting the tower would also delete mai let mainStats = getExampleMainStats() tower.mainStats = mainStats + /******************** + * Our example tower shouldn't exist in our empty database yet + * It is currently just in memory + ********************/ let retrievedTowers = await TOWER_REPO.find({ where: { name: tower.name, @@ -79,10 +96,17 @@ test("Store a tower and add main stats, deleting the tower would also delete mai expect(retrievedTowers.length).toBe(0) + /******************** + * Saving our tower should also save its main stats + ********************/ await TOWER_REPO.save(tower) expect(await TOWER_REPO.count()).toBe(1) expect(await MAIN_STATS_REPO.count()).toBe(1) + /******************** + * Querying the tower should also load its main stats + * With the expected column entries + ********************/ retrievedTowers = await TOWER_REPO.find({ where: { name: tower.name, @@ -96,26 +120,35 @@ test("Store a tower and add main stats, deleting the tower would also delete mai expect(retrievedTower.name).toBe(tower.name) expect(retrievedTower.mainStats.buildCost).toBe(tower.mainStats.buildCost) + /******************** + * Removing the tower should also remove its mainstats + ********************/ await TOWER_REPO.remove(retrievedTower) expect(await TOWER_REPO.count()).toBe(0) expect(await MAIN_STATS_REPO.count()).toBe(0) }) -test("Be able to store abilities and ability levels of a tower, deleting tower would remove ability and ability levels", async () => { +test("3. Be able to store abilities and ability levels of a tower, deleting tower would remove ability and ability levels", async () => { const TOWER_REPO = getRepository(Tower, "test") const ABILITY_REPO = getRepository(Ability, "test") const ABILITY_LEVEL_REPO = getRepository(AbilityLevel, "test") + /******************** + * We should start with an empty database + ********************/ expect(await TOWER_REPO.count()).toBe(0) expect(await ABILITY_REPO.count()).toBe(0) expect(await ABILITY_LEVEL_REPO.count()).toBe(0) + /******************** + * Saving a tower should also save its + * ability and ability levels + ********************/ let tower = getExampleTower() let ability1 = new Ability() ability1.name = "poison arrows" - ability1.description = - "Poisons anemies, causing them to take True damage over a three of seconds. Effects does not stack. True damage ignores any armore or magic resistance that an enemy has. Every upgrade level increases the damage dealt per second." + ability1.description = "Poisons enemies" let ability1level1 = new AbilityLevel() ability1level1.level = 1 @@ -129,6 +162,9 @@ test("Be able to store abilities and ability levels of a tower, deleting tower w expect(await ABILITY_REPO.count()).toBe(1) expect(await ABILITY_LEVEL_REPO.count()).toBe(1) + /******************** + * Querying the tower should also load its main stats + ********************/ let retrievedTowers = await TOWER_REPO.find({ where: { name: tower.name, @@ -138,6 +174,9 @@ test("Be able to store abilities and ability levels of a tower, deleting tower w expect(retrievedTowers.length).toBe(1) + /******************** + * Querying an ability should also load its levels + ********************/ let retrievedTower = retrievedTowers[0] let abilities = await ABILITY_REPO.find({ where: { @@ -150,10 +189,9 @@ test("Be able to store abilities and ability levels of a tower, deleting tower w expect(retrievedTower.abilities[0].name).toBe(ability1.name) expect(abilities[0].levels[0].cost).toBe(250) - expect(await TOWER_REPO.count()).toBe(1) - expect(await ABILITY_REPO.count()).toBe(1) - expect(await ABILITY_LEVEL_REPO.count()).toBe(1) - + /******************** + * Removing a tower should also remove its ability and ability levels + ********************/ await TOWER_REPO.remove(retrievedTower) expect(await TOWER_REPO.count()).toBe(0) expect(await ABILITY_REPO.count()).toBe(0) From 3663f643ba1f7bb7c83200e508aa184c2cd34882 Mon Sep 17 00:00:00 2001 From: Mithi Date: Fri, 30 Oct 2020 13:35:53 +0800 Subject: [PATCH 06/19] test: Move test resolvers to own modules --- jest.config.js | 2 +- tests/{ => resolvers}/__snapshots__/ASCENDING_TOWER_IDS.ts | 0 .../__snapshots__/ATTACK_TOWER_FIRE_INTERVAL_DESCEND.ts | 0 tests/{ => resolvers}/__snapshots__/ATTACK_TOWER_TYPES.ts | 0 tests/{ => resolvers}/__snapshots__/BARRACKS_TOWERS.ts | 0 tests/{ => resolvers}/tower_resolver.test.ts | 4 ++-- 6 files changed, 3 insertions(+), 3 deletions(-) rename tests/{ => resolvers}/__snapshots__/ASCENDING_TOWER_IDS.ts (100%) rename tests/{ => resolvers}/__snapshots__/ATTACK_TOWER_FIRE_INTERVAL_DESCEND.ts (100%) rename tests/{ => resolvers}/__snapshots__/ATTACK_TOWER_TYPES.ts (100%) rename tests/{ => resolvers}/__snapshots__/BARRACKS_TOWERS.ts (100%) rename tests/{ => resolvers}/tower_resolver.test.ts (96%) diff --git a/jest.config.js b/jest.config.js index a3b8c51..286a9db 100644 --- a/jest.config.js +++ b/jest.config.js @@ -3,5 +3,5 @@ module.exports = { maxWorkers: 1, preset: "ts-jest", testEnvironment: "node", - testMatch: ["**/tests/*.[jt]s?(x)"], + testMatch: ["**/tests/*.[jt]s?(x)", "**/tests/*/*.[jt]s?(x)"], } diff --git a/tests/__snapshots__/ASCENDING_TOWER_IDS.ts b/tests/resolvers/__snapshots__/ASCENDING_TOWER_IDS.ts similarity index 100% rename from tests/__snapshots__/ASCENDING_TOWER_IDS.ts rename to tests/resolvers/__snapshots__/ASCENDING_TOWER_IDS.ts diff --git a/tests/__snapshots__/ATTACK_TOWER_FIRE_INTERVAL_DESCEND.ts b/tests/resolvers/__snapshots__/ATTACK_TOWER_FIRE_INTERVAL_DESCEND.ts similarity index 100% rename from tests/__snapshots__/ATTACK_TOWER_FIRE_INTERVAL_DESCEND.ts rename to tests/resolvers/__snapshots__/ATTACK_TOWER_FIRE_INTERVAL_DESCEND.ts diff --git a/tests/__snapshots__/ATTACK_TOWER_TYPES.ts b/tests/resolvers/__snapshots__/ATTACK_TOWER_TYPES.ts similarity index 100% rename from tests/__snapshots__/ATTACK_TOWER_TYPES.ts rename to tests/resolvers/__snapshots__/ATTACK_TOWER_TYPES.ts diff --git a/tests/__snapshots__/BARRACKS_TOWERS.ts b/tests/resolvers/__snapshots__/BARRACKS_TOWERS.ts similarity index 100% rename from tests/__snapshots__/BARRACKS_TOWERS.ts rename to tests/resolvers/__snapshots__/BARRACKS_TOWERS.ts diff --git a/tests/tower_resolver.test.ts b/tests/resolvers/tower_resolver.test.ts similarity index 96% rename from tests/tower_resolver.test.ts rename to tests/resolvers/tower_resolver.test.ts index c34fc60..4d6469d 100644 --- a/tests/tower_resolver.test.ts +++ b/tests/resolvers/tower_resolver.test.ts @@ -1,9 +1,9 @@ import { createConnection, getConnection } from "typeorm" import { buildSchema } from "type-graphql" -import { TowerResolver } from "../src/resolvers/TowerResolver" +import { TowerResolver } from "../../src/resolvers/TowerResolver" import { ApolloServer, gql } from "apollo-server" import { createTestClient } from "apollo-server-testing" -import seed from "../src/seed" +import seed from "../../src/seed" import ascendingTowerIds from "./__snapshots__/ASCENDING_TOWER_IDS" import attackTowersTypes from "./__snapshots__/ATTACK_TOWER_TYPES" import attackTowersFireIntervalDescending from "./__snapshots__/ATTACK_TOWER_FIRE_INTERVAL_DESCEND" From 31de65660ed2270a71bc197f63292300b084e939 Mon Sep 17 00:00:00 2001 From: Mithi Date: Fri, 30 Oct 2020 17:08:41 +0800 Subject: [PATCH 07/19] Update scripts in package.lock --- package.json | 6 +++--- src/services/AbilityService.ts | 2 +- src/services/utils.ts | 2 +- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/package.json b/package.json index f784e81..a677d6a 100644 --- a/package.json +++ b/package.json @@ -13,12 +13,12 @@ "db:e2e": "bash ./scripts/run_end_to_end.sh", "db:create": "bash ./scripts/run_db_create.sh", "db:migrate-all": "rm -rf ./dist/migrations && npm run tsc && typeorm migration:run", - "db:create-migrate": "npm run db:create && npm run db:migrate-all-", + "db:create-migrate": "npm run db:create && npm run db:migrate-all", "db:update-data": "bash ./scripts/run_save_data.sh", "db:seed-json": "npm run tsc && node dist/seed/populate.js", "db:drop": "bash ./scripts/run_db_cleanup.sh", - "test": "jest", - "test:resolver": "jest -i tests/tower_resolver.test.ts" + "test": "jest --verbose", + "test:resolver": "jest -i tests/resolvers/tower_resolver.test.ts" }, "repository": { "type": "git", diff --git a/src/services/AbilityService.ts b/src/services/AbilityService.ts index 72512c2..f73ac61 100644 --- a/src/services/AbilityService.ts +++ b/src/services/AbilityService.ts @@ -21,7 +21,7 @@ export class AbilityService { const sortExpr = `ORDER BY ${sortColumns}` const filterExpr = `WHERE (${kingdoms}) AND (${towerTypes})` const query = `${TABLE_EXPRESSION} ${filterExpr} ${sortExpr} ${pageExpr}` - console.log(query) + //console.log(query) return await getConnection().query(query) } diff --git a/src/services/utils.ts b/src/services/utils.ts index ac181a8..ecf5692 100644 --- a/src/services/utils.ts +++ b/src/services/utils.ts @@ -32,7 +32,7 @@ const buildQueryExpression = ( const sortExpr = `ORDER BY ${sortColumns}` const pageExpr = `LIMIT ${take} OFFSET ${skip}` const queryExpression = `SELECT * FROM ${tableExpr} ${filterExpr} ${sortExpr} ${pageExpr}` - console.log(queryExpression) + //console.log(queryExpression) return queryExpression } From b9e0c0deee364eedd63500ebcbfc8706572890c6 Mon Sep 17 00:00:00 2001 From: Mithi Date: Fri, 30 Oct 2020 17:09:11 +0800 Subject: [PATCH 08/19] test: Don't populate tower at each test since we run test in parallel --- tests/seed.test.ts | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/tests/seed.test.ts b/tests/seed.test.ts index db099ee..595926b 100644 --- a/tests/seed.test.ts +++ b/tests/seed.test.ts @@ -13,11 +13,11 @@ import populateBarracksStats from "../src/seed/BarracksStats" import { populateTowers, populateAbilities } from "../src/seed/Tower" import populateBuildSequence from "../src/seed/BuildSequence" -beforeEach(async () => { +beforeAll(async () => { await createConnection("test") }) -afterEach(async () => { +afterAll(async () => { await getConnection("test").close() }) @@ -41,7 +41,6 @@ test("2. After populating BarracksStats and AttackStats, they should have the ex expect(barracksCount).toBe(0) expect(attackCount).toBe(0) - await populateTowers({ dbName: "test", verbose: false }) await populateBarracksStats({ dbName: "test", verbose: false }) await populateAttackStats({ dbName: "test", verbose: false }) @@ -57,7 +56,6 @@ test("3. After populating abilities and ability levels, they should have the exp expect(abilityCount).toBe(0) expect(abilityLevelCount).toBe(0) - await populateTowers({ dbName: "test", verbose: false }) await populateAbilities({ dbName: "test", verbose: false }) abilityCount = await getRepository(Ability, "test").count() @@ -70,7 +68,6 @@ test("4. After populating build sequences, they should have the expected number let buildSequenceCount = await getRepository(BuildSequence, "test").count() expect(buildSequenceCount).toBe(0) - await populateTowers({ dbName: "test", verbose: false }) await populateBuildSequence({ dbName: "test", verbose: false }) buildSequenceCount = await getRepository(BuildSequence, "test").count() From fa4ce9c6e9375ece4bb08b56ebd94414a801fd4a Mon Sep 17 00:00:00 2001 From: Mithi Date: Fri, 30 Oct 2020 17:09:38 +0800 Subject: [PATCH 09/19] test: Add bullet numbering for each test description --- tests/resolvers/tower_resolver.test.ts | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/tests/resolvers/tower_resolver.test.ts b/tests/resolvers/tower_resolver.test.ts index 4d6469d..61a0588 100644 --- a/tests/resolvers/tower_resolver.test.ts +++ b/tests/resolvers/tower_resolver.test.ts @@ -18,7 +18,7 @@ afterAll(async () => { await getConnection("test").close() }) -test("Be able to get towers, ids would be sorted in ascending order by default", async () => { +test("1. Be able to get towers, ids would be sorted in ascending order by default", async () => { const schema = await buildSchema({ resolvers: [TowerResolver] }) const { query } = createTestClient(new ApolloServer({ schema })) @@ -33,7 +33,7 @@ test("Be able to get towers, ids would be sorted in ascending order by default", expect(result).toMatchInlineSnapshot(ascendingTowerIds()) }) -test("Be able to get attack towers, by default result will be sorted by id in ascending order", async () => { +test("2. Be able to get attack towers, by default result will be sorted by id in ascending order", async () => { const schema = await buildSchema({ resolvers: [TowerResolver] }) const { query } = createTestClient(new ApolloServer({ schema })) @@ -48,7 +48,7 @@ test("Be able to get attack towers, by default result will be sorted by id in as expect(result).toMatchInlineSnapshot(attackTowersTypes()) }) -test("Be able to get attack towers sorted by fire interval in descending order", async () => { +test("3. Be able to get attack towers sorted by fire interval in descending order", async () => { const schema = await buildSchema({ resolvers: [TowerResolver] }) const { query } = createTestClient(new ApolloServer({ schema })) @@ -69,7 +69,7 @@ test("Be able to get attack towers sorted by fire interval in descending order", expect(result).toMatchInlineSnapshot(attackTowersFireIntervalDescending()) }) -test("Be able to get barracks towers in correct order", async () => { +test("4. Be able to get barracks towers in correct order", async () => { const schema = await buildSchema({ resolvers: [TowerResolver] }) const { query } = createTestClient(new ApolloServer({ schema })) From d997485cc96ab6d0d300324b72f249929022b84f Mon Sep 17 00:00:00 2001 From: Mithi Date: Fri, 30 Oct 2020 18:03:46 +0800 Subject: [PATCH 10/19] Add log of time interval for seeding database --- tests/resolvers/tower_resolver.test.ts | 3 +++ tests/seed.test.ts | 3 +++ tests/tower_db.test.ts | 3 +++ 3 files changed, 9 insertions(+) diff --git a/tests/resolvers/tower_resolver.test.ts b/tests/resolvers/tower_resolver.test.ts index 61a0588..ff57d6c 100644 --- a/tests/resolvers/tower_resolver.test.ts +++ b/tests/resolvers/tower_resolver.test.ts @@ -10,8 +10,11 @@ import attackTowersFireIntervalDescending from "./__snapshots__/ATTACK_TOWER_FIR import barracksTowers from "./__snapshots__/BARRACKS_TOWERS" beforeAll(async () => { + const t0 = Date.now() await createConnection("test") await seed({ dbName: "test", verbose: false }) + const t1 = Date.now() + console.log(` 👩‍🔬 Connected and populated database in ${t1 - t0}ms`) }) afterAll(async () => { diff --git a/tests/seed.test.ts b/tests/seed.test.ts index 595926b..f3ef95e 100644 --- a/tests/seed.test.ts +++ b/tests/seed.test.ts @@ -14,7 +14,10 @@ import { populateTowers, populateAbilities } from "../src/seed/Tower" import populateBuildSequence from "../src/seed/BuildSequence" beforeAll(async () => { + const t0 = Date.now() await createConnection("test") + const t1 = Date.now() + console.log(` 👩‍🔬 Connected database in ${t1 - t0}ms`) }) afterAll(async () => { diff --git a/tests/tower_db.test.ts b/tests/tower_db.test.ts index 9d47544..fadede8 100644 --- a/tests/tower_db.test.ts +++ b/tests/tower_db.test.ts @@ -27,7 +27,10 @@ const EXAMPLE_TOWER_DATA = { } beforeAll(async () => { + const t0 = Date.now() await createConnection("test") + const t1 = Date.now() + console.log(` 👩‍🔬 Connected database in ${t1 - t0}ms`) }) afterAll(async () => { From 9213d008e4e43c556946941331f47bbc920625a5 Mon Sep 17 00:00:00 2001 From: Mithi Date: Sat, 31 Oct 2020 12:11:19 +0800 Subject: [PATCH 11/19] chore: Update jest config with correct test match --- jest.config.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/jest.config.js b/jest.config.js index 286a9db..33408bc 100644 --- a/jest.config.js +++ b/jest.config.js @@ -3,5 +3,5 @@ module.exports = { maxWorkers: 1, preset: "ts-jest", testEnvironment: "node", - testMatch: ["**/tests/*.[jt]s?(x)", "**/tests/*/*.[jt]s?(x)"], + testMatch: ["**/tests/*.test.[jt]s?(x)", "**/tests/*/*.test.[jt]s?(x)"], } From 189813b71a4c51a884746c04786bc874a74e97fb Mon Sep 17 00:00:00 2001 From: Mithi Date: Sat, 31 Oct 2020 12:12:46 +0800 Subject: [PATCH 12/19] FIX: Use appropriate database based on environment --- src/services/AbilityService.ts | 12 +++++++----- src/services/BuildSequenceService.ts | 4 +++- 2 files changed, 10 insertions(+), 6 deletions(-) diff --git a/src/services/AbilityService.ts b/src/services/AbilityService.ts index f73ac61..978ec6c 100644 --- a/src/services/AbilityService.ts +++ b/src/services/AbilityService.ts @@ -3,6 +3,8 @@ import { getConnection } from "typeorm" import { buildFilterExpression, buildSortExpression } from "./utils" import { TABLE_EXPRESSION } from "./utilsAbilityTableExpr" +const DB_NAME = process.env.NODE_ENV === "test" ? "test" : "default" + const nothingLeft = (arrays: any[]): boolean => { return arrays.some(list => list.length === 0) } @@ -22,28 +24,28 @@ export class AbilityService { const filterExpr = `WHERE (${kingdoms}) AND (${towerTypes})` const query = `${TABLE_EXPRESSION} ${filterExpr} ${sortExpr} ${pageExpr}` //console.log(query) - return await getConnection().query(query) + return await getConnection(DB_NAME).query(query) } async abilitiesByTowerId(id: Number) { const query = `${TABLE_EXPRESSION} WHERE t4.id = ${id}` - return await getConnection().query(query) + return await getConnection(DB_NAME).query(query) } async abilitiesByTowerName(name: String) { const query = `${TABLE_EXPRESSION} WHERE t4.name = '${name}'` - return await getConnection().query(query) + return await getConnection(DB_NAME).query(query) } async abilityById(id: Number) { const query = `${TABLE_EXPRESSION} WHERE ability_table."abilityId" = '${id}'` - const results = await getConnection().query(query) + const results = await getConnection(DB_NAME).query(query) return results.length !== 0 ? results[0] : null } async abilityByName(name: String) { const query = `${TABLE_EXPRESSION} WHERE ability_table."abilityName" = '${name}'` - const results = await getConnection().query(query) + const results = await getConnection(DB_NAME).query(query) return results.length !== 0 ? results[0] : null } } diff --git a/src/services/BuildSequenceService.ts b/src/services/BuildSequenceService.ts index 3357b27..e493017 100644 --- a/src/services/BuildSequenceService.ts +++ b/src/services/BuildSequenceService.ts @@ -4,8 +4,10 @@ import { buildFilterExpression, buildSortExpression } from "./utils" import { convertToBuildSequenceShape } from "./utilsBuildSequence" import { TABLE_EXPRESSION } from "./utilsBuildSequenceTableExpr" +const DB_NAME = process.env.NODE_ENV === "test" ? "test" : "default" + const findOneBuildSequence = async (queryExpression: string) => { - const results = await getConnection().query(queryExpression) + const results = await getConnection(DB_NAME).query(queryExpression) const result = results.length !== 0 ? results[0] : null if (result === null) { return null From d0c07fe125a5b347e5a07216122bdac8d28a4bea Mon Sep 17 00:00:00 2001 From: Mithi Date: Sat, 31 Oct 2020 12:13:21 +0800 Subject: [PATCH 13/19] Refactor duplicate code --- tests/resolvers/tower_resolver.test.ts | 35 +++++++++----------------- 1 file changed, 12 insertions(+), 23 deletions(-) diff --git a/tests/resolvers/tower_resolver.test.ts b/tests/resolvers/tower_resolver.test.ts index ff57d6c..23109d3 100644 --- a/tests/resolvers/tower_resolver.test.ts +++ b/tests/resolvers/tower_resolver.test.ts @@ -3,28 +3,29 @@ import { buildSchema } from "type-graphql" import { TowerResolver } from "../../src/resolvers/TowerResolver" import { ApolloServer, gql } from "apollo-server" import { createTestClient } from "apollo-server-testing" -import seed from "../../src/seed" import ascendingTowerIds from "./__snapshots__/ASCENDING_TOWER_IDS" import attackTowersTypes from "./__snapshots__/ATTACK_TOWER_TYPES" import attackTowersFireIntervalDescending from "./__snapshots__/ATTACK_TOWER_FIRE_INTERVAL_DESCEND" import barracksTowers from "./__snapshots__/BARRACKS_TOWERS" +import { DocumentNode } from "graphql" beforeAll(async () => { - const t0 = Date.now() await createConnection("test") - await seed({ dbName: "test", verbose: false }) - const t1 = Date.now() - console.log(` 👩‍🔬 Connected and populated database in ${t1 - t0}ms`) }) afterAll(async () => { await getConnection("test").close() }) -test("1. Be able to get towers, ids would be sorted in ascending order by default", async () => { +const executeTest = async (testQuery: DocumentNode, correctAnswer: string) => { const schema = await buildSchema({ resolvers: [TowerResolver] }) const { query } = createTestClient(new ApolloServer({ schema })) + const result = await query({ query: testQuery }) + expect(result).toMatchInlineSnapshot(correctAnswer) +} + +test("1. Be able to get towers, ids would be sorted in ascending order by default", async () => { const testQuery = gql` { towers { @@ -32,14 +33,11 @@ test("1. Be able to get towers, ids would be sorted in ascending order by defaul } } ` - const result = await query({ query: testQuery }) - expect(result).toMatchInlineSnapshot(ascendingTowerIds()) + + await executeTest(testQuery, ascendingTowerIds()) }) test("2. Be able to get attack towers, by default result will be sorted by id in ascending order", async () => { - const schema = await buildSchema({ resolvers: [TowerResolver] }) - const { query } = createTestClient(new ApolloServer({ schema })) - const testQuery = gql` { attackTowers { @@ -47,14 +45,10 @@ test("2. Be able to get attack towers, by default result will be sorted by id in } } ` - const result = await query({ query: testQuery }) - expect(result).toMatchInlineSnapshot(attackTowersTypes()) + await executeTest(testQuery, attackTowersTypes()) }) test("3. Be able to get attack towers sorted by fire interval in descending order", async () => { - const schema = await buildSchema({ resolvers: [TowerResolver] }) - const { query } = createTestClient(new ApolloServer({ schema })) - const testQuery = gql` { attackTowers( @@ -68,14 +62,10 @@ test("3. Be able to get attack towers sorted by fire interval in descending orde } } ` - const result = await query({ query: testQuery }) - expect(result).toMatchInlineSnapshot(attackTowersFireIntervalDescending()) + await executeTest(testQuery, attackTowersFireIntervalDescending()) }) test("4. Be able to get barracks towers in correct order", async () => { - const schema = await buildSchema({ resolvers: [TowerResolver] }) - const { query } = createTestClient(new ApolloServer({ schema })) - const testQuery = gql` { barracksTowers( @@ -91,6 +81,5 @@ test("4. Be able to get barracks towers in correct order", async () => { } } ` - const result = await query({ query: testQuery }) - expect(result).toMatchInlineSnapshot(barracksTowers()) + await executeTest(testQuery, barracksTowers()) }) From 93d83b14929e6c1897ca3dd8bc6b5b46a4316947 Mon Sep 17 00:00:00 2001 From: Mithi Date: Sat, 31 Oct 2020 16:28:59 +0800 Subject: [PATCH 14/19] Add additional database to separate tests of resolvers to others - We don't want to populate resolvers over and over again for each test file, so we will use a frozen prepopulated database. (the other non-resolver tests mutate the database). --- .env.sample | 3 ++- ormconfig.js | 15 ++++++++++++++- scripts/run_db_cleanup.sh | 3 ++- scripts/run_db_create.sh | 6 +++++- 4 files changed, 23 insertions(+), 4 deletions(-) diff --git a/.env.sample b/.env.sample index b4b417a..7b1253d 100644 --- a/.env.sample +++ b/.env.sample @@ -1,3 +1,4 @@ DB_PASSWORD=password DB_DEFAULT_URL="postgres://kingdom_rush_user:password@localhost:5432/kingdom_rush_db" -DB_TEST_URL="postgres://kingdom_rush_user:password@localhost:5432/test_db" \ No newline at end of file +DB_TEST_URL="postgres://kingdom_rush_user:password@localhost:5432/test_db" +DB_EMPTY_TEST_URL="postgres://kingdom_rush_user:password@localhost:5432/empty_test_db" \ No newline at end of file diff --git a/ormconfig.js b/ormconfig.js index 9497298..0f3d12a 100644 --- a/ormconfig.js +++ b/ormconfig.js @@ -14,9 +14,22 @@ module.exports = [ }, }, { - url: `${process.env.DB_TEST_URL}`, name: "test", type: "postgres", + url: `${process.env.DB_TEST_URL}`, + entities: ["src/models/*.ts"], + logging: false, + synchronize: false, + dropSchema: false, + migrations: ["src/migrations/*.ts"], + cli: { + migrationsDir: "src/migrations", + }, + }, + { + name: "empty_test", + type: "postgres", + url: `${process.env.DB_EMPTY_TEST_URL}`, entities: ["src/models/*.ts"], logging: false, synchronize: true, diff --git a/scripts/run_db_cleanup.sh b/scripts/run_db_cleanup.sh index 7cf40ab..9259083 100644 --- a/scripts/run_db_cleanup.sh +++ b/scripts/run_db_cleanup.sh @@ -1,8 +1,9 @@ # Drops all tables, enums in kingdom_rush_db then drops this database and user psql -c "SELECT rolname FROM pg_catalog.pg_roles"; psql kingdom_rush_user -h localhost -d kingdom_rush_db --pset=pager -f ./scripts/db_drop.sql; -psql kingdom_rush_user -h localhost -d kingdom_rush_db --pset=pager -f ./scripts/db_gen_info.sql; +psql kingdom_rush_user -h localhost -d test_db --pset=pager -f ./scripts/db_drop.sql; +psql -c "DROP DATABASE empty_test_db"; psql -c "DROP DATABASE test_db"; psql -c "DROP DATABASE kingdom_rush_db"; psql -c "DROP ROLE kingdom_rush_user"; diff --git a/scripts/run_db_create.sh b/scripts/run_db_create.sh index 045e1d2..ff13c47 100644 --- a/scripts/run_db_create.sh +++ b/scripts/run_db_create.sh @@ -1,4 +1,7 @@ -# Creates a role named kingdom_rush_user with databases named test_db and kingdom_rush_db +# Creates a role named kingdom_rush_user with databases named +# - empty_test_db +# - test_db +# - kingdom_rush_db # Load all variables in dotenv file export $(egrep -v '^#' .env | xargs); @@ -14,6 +17,7 @@ psql -c "CREATE ROLE kingdom_rush_user WITH LOGIN PASSWORD '${DB_PASSWORD}';"; psql -c "ALTER ROLE kingdom_rush_user CREATEDB;"; psql postgres -U kingdom_rush_user -c "CREATE DATABASE kingdom_rush_db;"; psql postgres -U kingdom_rush_user -c "CREATE DATABASE test_db;"; +psql postgres -U kingdom_rush_user -c "CREATE DATABASE empty_test_db;"; echo "Current existing roles:" psql -c "SELECT rolname FROM pg_catalog.pg_roles"; From 0c5dcc451fa43e91966c1d40bb6f2c716c0533bc Mon Sep 17 00:00:00 2001 From: Mithi Date: Sat, 31 Oct 2020 16:41:39 +0800 Subject: [PATCH 15/19] Update scripts - remove unused scripts - change script name from migrate-all to migrate - Include migration of tests in test migrate script - Update command to run resolver tests --- package.json | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/package.json b/package.json index a677d6a..84b0c81 100644 --- a/package.json +++ b/package.json @@ -5,20 +5,19 @@ "main": "dist/index.js", "scripts": { "tsc": "tsc -p tsconfig.json", - "start": "nodemon -e ts --exec \"npm run compile\"", + "start": "nodemon --ignore tests -e ts --exec \"npm run compile\"", "build": "npm run format && npm run compile", "compile": "npm run tsc && node dist/index.js", "format": "prettier --config ./.prettierrc.yaml --write ./src/*.ts", "setup": "bash ./scripts/run_setup.sh", "db:e2e": "bash ./scripts/run_end_to_end.sh", "db:create": "bash ./scripts/run_db_create.sh", - "db:migrate-all": "rm -rf ./dist/migrations && npm run tsc && typeorm migration:run", - "db:create-migrate": "npm run db:create && npm run db:migrate-all", + "db:migrate": "rm -rf ./dist/migrations && npm run tsc && typeorm migration:run && ts-node ./node_modules/typeorm/cli.js migration:run -c \"test\";", "db:update-data": "bash ./scripts/run_save_data.sh", "db:seed-json": "npm run tsc && node dist/seed/populate.js", "db:drop": "bash ./scripts/run_db_cleanup.sh", - "test": "jest --verbose", - "test:resolver": "jest -i tests/resolvers/tower_resolver.test.ts" + "test:resolver": "jest --testPathPattern=tests/resolvers --verbose", + "test": "jest --verbose" }, "repository": { "type": "git", From 0ea78ed17e55739f97e45fec9c8be8403bf9cd8b Mon Sep 17 00:00:00 2001 From: Mithi Date: Sat, 31 Oct 2020 16:43:11 +0800 Subject: [PATCH 16/19] Populate test_db upon setup --- scripts/run_save_data.sh | 2 +- scripts/run_setup.sh | 19 +++++++++++++++---- 2 files changed, 16 insertions(+), 5 deletions(-) diff --git a/scripts/run_save_data.sh b/scripts/run_save_data.sh index 70603e9..c957a57 100644 --- a/scripts/run_save_data.sh +++ b/scripts/run_save_data.sh @@ -1,5 +1,5 @@ # Generates json files from raw/yaml files -# Populates the database tables using these table files +# Populates the "kingdom_rush_db" database tables using these table files # Gets the all data from the tables and saves it both as txt and csv python ./scripts/json-towers.py; python ./scripts/json-barracks-stats.py; diff --git a/scripts/run_setup.sh b/scripts/run_setup.sh index aa74d92..b131ad6 100644 --- a/scripts/run_setup.sh +++ b/scripts/run_setup.sh @@ -1,7 +1,18 @@ npm run db:create; npm install; -cp .env.sample .env -npm run db:migrate-all; -npm run test; -psql kingdom_rush_user -h localhost -d kingdom_rush_db --pset=pager -f ./scripts/db_gen_info.sql; +cp .env.sample .env; +# migrate and populate kingdom_rush_db +npm run db:migrate; +psql kingdom_rush_user -h localhost -d kingdom_rush_db -f ./scripts/db_load_csv.sql; + +# migrate and populate test_db +psql kingdom_rush_user -h localhost -d test_db -f ./scripts/db_load_csv.sql; +psql kingdom_rush_user -h localhost -d test_db --pset=pager -f ./scripts/db_gen_info.sql; +psql kingdom_rush_user -h localhost -d test_db --pset=pager -f ./scripts/db_table_info.sql; + +# sleep for a while to help prevent errors in testing the database +sleep 5 + +# run tests +npm run test From 417db157f07e30810d058ed49b9fa49c69ed8bd7 Mon Sep 17 00:00:00 2001 From: Mithi Date: Sat, 31 Oct 2020 16:43:33 +0800 Subject: [PATCH 17/19] Update ts config include and exclude directories --- tsconfig.json | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tsconfig.json b/tsconfig.json index b436183..9717222 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -20,6 +20,6 @@ "noFallthroughCasesInSwitch": true, "allowSyntheticDefaultImports": true }, - "include": ["./src"], - "exclude": ["./node_modules", "./test"] + "include": ["src"], + "exclude": ["node_modules", "tests", "dist"] } From 77a405fbd4df88bceb40e5999e160f152aa518b7 Mon Sep 17 00:00:00 2001 From: Mithi Date: Sat, 31 Oct 2020 16:44:03 +0800 Subject: [PATCH 18/19] Use empty_test db for non resolver tests (where mutation is allowed) --- tests/seed.test.ts | 46 ++++++++++++++++++++---------------------- tests/tower_db.test.ts | 21 +++++++++---------- 2 files changed, 32 insertions(+), 35 deletions(-) diff --git a/tests/seed.test.ts b/tests/seed.test.ts index f3ef95e..690de2d 100644 --- a/tests/seed.test.ts +++ b/tests/seed.test.ts @@ -13,66 +13,64 @@ import populateBarracksStats from "../src/seed/BarracksStats" import { populateTowers, populateAbilities } from "../src/seed/Tower" import populateBuildSequence from "../src/seed/BuildSequence" +const DB_NAME = "empty_test" beforeAll(async () => { - const t0 = Date.now() - await createConnection("test") - const t1 = Date.now() - console.log(` 👩‍🔬 Connected database in ${t1 - t0}ms`) + await createConnection(DB_NAME) }) afterAll(async () => { - await getConnection("test").close() + await getConnection(DB_NAME).close() }) test("1. After populating Towers and MainStats, they should have the expected number of entries", async () => { - let towerCount = await getRepository(Tower, "test").count() - let mainStatsCount = await getRepository(MainStats, "test").count() + let towerCount = await getRepository(Tower, DB_NAME).count() + let mainStatsCount = await getRepository(MainStats, DB_NAME).count() expect(towerCount).toBe(0) expect(mainStatsCount).toBe(0) - await populateTowers({ dbName: "test", verbose: false }) - towerCount = await getRepository(Tower, "test").count() - mainStatsCount = await getRepository(MainStats, "test").count() + await populateTowers({ dbName: DB_NAME, verbose: false }) + towerCount = await getRepository(Tower, DB_NAME).count() + mainStatsCount = await getRepository(MainStats, DB_NAME).count() expect(towerCount).toBe(104) expect(mainStatsCount).toBe(104) }) test("2. After populating BarracksStats and AttackStats, they should have the expected number of entries", async () => { - let barracksCount = await getRepository(BarracksStats, "test").count() - let attackCount = await getRepository(AttackStats, "test").count() + let barracksCount = await getRepository(BarracksStats, DB_NAME).count() + let attackCount = await getRepository(AttackStats, DB_NAME).count() expect(barracksCount).toBe(0) expect(attackCount).toBe(0) - await populateBarracksStats({ dbName: "test", verbose: false }) - await populateAttackStats({ dbName: "test", verbose: false }) + await populateBarracksStats({ dbName: DB_NAME, verbose: false }) + await populateAttackStats({ dbName: DB_NAME, verbose: false }) - barracksCount = await getRepository(BarracksStats, "test").count() - attackCount = await getRepository(AttackStats, "test").count() + barracksCount = await getRepository(BarracksStats, DB_NAME).count() + attackCount = await getRepository(AttackStats, DB_NAME).count() expect(barracksCount).toBe(27) expect(attackCount).toBe(77) }) test("3. After populating abilities and ability levels, they should have the expected number of entries", async () => { - let abilityCount = await getRepository(Ability, "test").count() - let abilityLevelCount = await getRepository(AbilityLevel, "test").count() + let abilityCount = await getRepository(Ability, DB_NAME).count() + let abilityLevelCount = await getRepository(AbilityLevel, DB_NAME).count() expect(abilityCount).toBe(0) expect(abilityLevelCount).toBe(0) - await populateAbilities({ dbName: "test", verbose: false }) + await populateAbilities({ dbName: DB_NAME, verbose: false }) - abilityCount = await getRepository(Ability, "test").count() - abilityLevelCount = await getRepository(AbilityLevel, "test").count() + abilityCount = await getRepository(Ability, DB_NAME).count() + abilityLevelCount = await getRepository(AbilityLevel, DB_NAME).count() expect(abilityCount).toBe(87) expect(abilityLevelCount).toBe(228) }) test("4. After populating build sequences, they should have the expected number of entries", async () => { - let buildSequenceCount = await getRepository(BuildSequence, "test").count() + let buildSequenceCount = await getRepository(BuildSequence, DB_NAME).count() expect(buildSequenceCount).toBe(0) - await populateBuildSequence({ dbName: "test", verbose: false }) + await populateBuildSequence({ dbName: DB_NAME, verbose: false }) - buildSequenceCount = await getRepository(BuildSequence, "test").count() + buildSequenceCount = await getRepository(BuildSequence, DB_NAME).count() expect(buildSequenceCount).toBe(35) }) diff --git a/tests/tower_db.test.ts b/tests/tower_db.test.ts index fadede8..a45c942 100644 --- a/tests/tower_db.test.ts +++ b/tests/tower_db.test.ts @@ -2,6 +2,8 @@ import { createConnection, getConnection, getRepository } from "typeorm" import { Tower, MainStats, Ability, AbilityLevel } from "../src/models/" import { TowerType, TowerLevel, TowerKingdom } from "../src/definitions/enums" +const DB_NAME = "empty_test" + const getExampleTower = (): Tower => { let tower = new Tower() tower.name = "dwarven bombard" @@ -27,18 +29,15 @@ const EXAMPLE_TOWER_DATA = { } beforeAll(async () => { - const t0 = Date.now() - await createConnection("test") - const t1 = Date.now() - console.log(` 👩‍🔬 Connected database in ${t1 - t0}ms`) + await createConnection("empty_test") }) afterAll(async () => { - await getConnection("test").close() + await getConnection("empty_test").close() }) test("1. Be able to store, fetch, and remove a tower", async () => { - const TOWER_REPO = getRepository(Tower, "test") + const TOWER_REPO = getRepository(Tower, DB_NAME) /******************** * Our example tower shouldn't exist yet in our empty test database @@ -80,8 +79,8 @@ test("1. Be able to store, fetch, and remove a tower", async () => { }) test("2. Store a tower and add main stats deleting the tower would also delete main stats", async () => { - const TOWER_REPO = getRepository(Tower, "test") - const MAIN_STATS_REPO = getRepository(MainStats, "test") + const TOWER_REPO = getRepository(Tower, DB_NAME) + const MAIN_STATS_REPO = getRepository(MainStats, DB_NAME) let tower = getExampleTower() let mainStats = getExampleMainStats() @@ -132,9 +131,9 @@ test("2. Store a tower and add main stats deleting the tower would also delete m }) test("3. Be able to store abilities and ability levels of a tower, deleting tower would remove ability and ability levels", async () => { - const TOWER_REPO = getRepository(Tower, "test") - const ABILITY_REPO = getRepository(Ability, "test") - const ABILITY_LEVEL_REPO = getRepository(AbilityLevel, "test") + const TOWER_REPO = getRepository(Tower, DB_NAME) + const ABILITY_REPO = getRepository(Ability, DB_NAME) + const ABILITY_LEVEL_REPO = getRepository(AbilityLevel, DB_NAME) /******************** * We should start with an empty database From f3b19639faab847eeb7079d2977f2f497628c29f Mon Sep 17 00:00:00 2001 From: Mithi Date: Sat, 31 Oct 2020 16:44:18 +0800 Subject: [PATCH 19/19] test: Add first ability test --- .../resolvers/__snapshots__/ABILITY_BY_ID.ts | 35 +++++++++++++++ tests/resolvers/ability.test.ts | 45 +++++++++++++++++++ 2 files changed, 80 insertions(+) create mode 100644 tests/resolvers/__snapshots__/ABILITY_BY_ID.ts create mode 100644 tests/resolvers/ability.test.ts diff --git a/tests/resolvers/__snapshots__/ABILITY_BY_ID.ts b/tests/resolvers/__snapshots__/ABILITY_BY_ID.ts new file mode 100644 index 0000000..7589158 --- /dev/null +++ b/tests/resolvers/__snapshots__/ABILITY_BY_ID.ts @@ -0,0 +1,35 @@ +const result = () => { + return ` + Object { + "data": Object { + "abilityById": Object { + "abilityDescription": "Fills a zone with powerful healing roots. Allies over it heal over 4 seconds. Each upgrade level increases HP healed", + "abilityId": 85, + "abilityName": "Healing Roots", + "kingdom": "KRV", + "levelCosts": Array [ + 130, + 130, + 130, + ], + "numberOfLevels": 3, + "totalAbilityCost": 390, + "totalCostWithTowers": 1290, + "towerId": 104, + "towerImageUrl": "https://storage.googleapis.com/kingdom-rush-towers.appspot.com/krv-shaman4.png", + "towerName": "orc shaman, 4", + "towerType": "MAGE", + }, + }, + "errors": undefined, + "extensions": undefined, + "http": Object { + "headers": Headers { + Symbol(map): Object {}, + }, + }, + } +` +} + +export default result diff --git a/tests/resolvers/ability.test.ts b/tests/resolvers/ability.test.ts new file mode 100644 index 0000000..c4bf826 --- /dev/null +++ b/tests/resolvers/ability.test.ts @@ -0,0 +1,45 @@ +import { createConnection, getConnection } from "typeorm" +import { buildSchema } from "type-graphql" +import { AbilityResolver } from "../../src/resolvers/AbilityResolver" +import { ApolloServer, gql } from "apollo-server" +import { createTestClient } from "apollo-server-testing" +import ABILITY_BY_ID_RESULT from "./__snapshots__/ABILITY_BY_ID" +import { DocumentNode } from "graphql" + +beforeAll(async () => { + await createConnection("test") +}) + +afterAll(async () => { + await getConnection("test").close() +}) + +const executeTest = async (testQuery: DocumentNode, correctAnswer: string) => { + const schema = await buildSchema({ resolvers: [AbilityResolver] }) + const { query } = createTestClient(new ApolloServer({ schema })) + + const result = await query({ query: testQuery }) + expect(result).toMatchInlineSnapshot(correctAnswer) +} + +test("1. Be able to get ability data by its id", async () => { + const testQuery = gql` + { + abilityById(id: 85) { + abilityDescription + abilityId + abilityName + kingdom + levelCosts + numberOfLevels + totalAbilityCost + totalCostWithTowers + towerId + towerImageUrl + towerName + towerType + } + } + ` + await executeTest(testQuery, ABILITY_BY_ID_RESULT()) +})