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/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! diff --git a/jest.config.js b/jest.config.js index a3b8c51..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)"], + testMatch: ["**/tests/*.test.[jt]s?(x)", "**/tests/*/*.test.[jt]s?(x)"], } 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/package.json b/package.json index f784e81..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", - "test:resolver": "jest -i tests/tower_resolver.test.ts" + "test:resolver": "jest --testPathPattern=tests/resolvers --verbose", + "test": "jest --verbose" }, "repository": { "type": "git", 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"; 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 3ab337f..b131ad6 100644 --- a/scripts/run_setup.sh +++ b/scripts/run_setup.sh @@ -1,6 +1,18 @@ npm run db:create; npm install; -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 diff --git a/src/services/AbilityService.ts b/src/services/AbilityService.ts index 72512c2..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) } @@ -21,29 +23,29 @@ export class AbilityService { const sortExpr = `ORDER BY ${sortColumns}` const filterExpr = `WHERE (${kingdoms}) AND (${towerTypes})` const query = `${TABLE_EXPRESSION} ${filterExpr} ${sortExpr} ${pageExpr}` - console.log(query) - return await getConnection().query(query) + //console.log(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 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 } 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/__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/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()) +}) diff --git a/tests/tower_resolver.test.ts b/tests/resolvers/tower_resolver.test.ts similarity index 57% rename from tests/tower_resolver.test.ts rename to tests/resolvers/tower_resolver.test.ts index c34fc60..23109d3 100644 --- a/tests/tower_resolver.test.ts +++ b/tests/resolvers/tower_resolver.test.ts @@ -1,27 +1,31 @@ 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 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 () => { await createConnection("test") - await seed({ dbName: "test", verbose: false }) }) afterAll(async () => { await getConnection("test").close() }) -test("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 { @@ -29,14 +33,11 @@ test("Be able to get towers, ids would be sorted in ascending order by default", } } ` - const result = await query({ query: testQuery }) - expect(result).toMatchInlineSnapshot(ascendingTowerIds()) -}) -test("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 })) + 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 testQuery = gql` { attackTowers { @@ -44,14 +45,10 @@ test("Be able to get attack towers, by default result will be sorted by id in as } } ` - const result = await query({ query: testQuery }) - expect(result).toMatchInlineSnapshot(attackTowersTypes()) + await executeTest(testQuery, attackTowersTypes()) }) -test("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 })) - +test("3. Be able to get attack towers sorted by fire interval in descending order", async () => { const testQuery = gql` { attackTowers( @@ -65,14 +62,10 @@ test("Be able to get attack towers sorted by fire interval in descending order", } } ` - const result = await query({ query: testQuery }) - expect(result).toMatchInlineSnapshot(attackTowersFireIntervalDescending()) + await executeTest(testQuery, attackTowersFireIntervalDescending()) }) -test("Be able to get barracks towers in correct order", async () => { - const schema = await buildSchema({ resolvers: [TowerResolver] }) - const { query } = createTestClient(new ApolloServer({ schema })) - +test("4. Be able to get barracks towers in correct order", async () => { const testQuery = gql` { barracksTowers( @@ -88,6 +81,5 @@ test("Be able to get barracks towers in correct order", async () => { } } ` - const result = await query({ query: testQuery }) - expect(result).toMatchInlineSnapshot(barracksTowers()) + await executeTest(testQuery, barracksTowers()) }) diff --git a/tests/seed.test.ts b/tests/seed.test.ts index 8388903..690de2d 100644 --- a/tests/seed.test.ts +++ b/tests/seed.test.ts @@ -7,59 +7,70 @@ 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") +const DB_NAME = "empty_test" +beforeAll(async () => { + await createConnection(DB_NAME) }) -afterEach(async () => { - await getConnection("test").close() +afterAll(async () => { + 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 populateTowers({ dbName: "test", verbose: false }) - 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 populateTowers({ dbName: "test", verbose: false }) - 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, DB_NAME).count() + expect(buildSequenceCount).toBe(0) + + await populateBuildSequence({ dbName: DB_NAME, verbose: false }) + + 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 d04f42c..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" @@ -19,56 +21,75 @@ 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") + await createConnection("empty_test") }) afterAll(async () => { - await getConnection("test").close() + await getConnection("empty_test").close() }) -test("Store tower and fetch it", async () => { - const TOWER_REPO = getRepository(Tower, "test") - - const exampleTowerData = { - name: "Militia Barracks", - towerType: TowerType.BARRACKS, - level: TowerLevel.LVL1, - kingdom: TowerKingdom.KR, - } +test("1. Be able to store, fetch, and remove a tower", async () => { + const TOWER_REPO = getRepository(Tower, DB_NAME) + /******************** + * Our example tower shouldn't exist yet in our empty test database + ********************/ 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) + /******************** + * 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: 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) + /******************** + * 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 () => { - const TOWER_REPO = getRepository(Tower, "test") - const MAIN_STATS_REPO = getRepository(MainStats, "test") +test("2. Store a tower and add main stats deleting the tower would also delete main stats", async () => { + const TOWER_REPO = getRepository(Tower, DB_NAME) + const MAIN_STATS_REPO = getRepository(MainStats, DB_NAME) let tower = getExampleTower() 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, @@ -77,8 +98,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, @@ -92,26 +122,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", async () => { - const TOWER_REPO = getRepository(Tower, "test") - const ABILITY_REPO = getRepository(Ability, "test") - const ABILITY_LEVEL_REPO = getRepository(AbilityLevel, "test") +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, DB_NAME) + const ABILITY_REPO = getRepository(Ability, DB_NAME) + const ABILITY_LEVEL_REPO = getRepository(AbilityLevel, DB_NAME) + /******************** + * 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 @@ -125,6 +164,9 @@ test("Be able to store abilities and ability levels of a tower", async () => { 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, @@ -134,6 +176,9 @@ test("Be able to store abilities and ability levels of a tower", async () => { expect(retrievedTowers.length).toBe(1) + /******************** + * Querying an ability should also load its levels + ********************/ let retrievedTower = retrievedTowers[0] let abilities = await ABILITY_REPO.find({ where: { @@ -146,6 +191,9 @@ 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) + /******************** + * 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) 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"] }