Skip to content
This repository has been archived by the owner on Nov 24, 2023. It is now read-only.

Commit

Permalink
Merge pull request #74 from mithi/tests/abilities-tests
Browse files Browse the repository at this point in the history
It is better to have two separate test environments (two test databases),
one for testing resolvers (which is closer to an integration test), and the other for testing everything else.

When testing graphql resolvers, seeding the database should only be done once as this is a slow operation. 
Currently, using 'globalSetup` and `globalTeardown` with jest doesn't work for setting up the `typeorm` database.
The tests are not able to find the connection. 
See:
#73
typeorm/typeorm#5308
jestjs/jest#10178

It is also not efficient to remove all of the entries for this database in order to start with a clean slate for
testing the models and testing the seeding operations. So what we do here is we have two test databases. 
1. a prepopulated frozen test database (called `test_db`) to be used by the graphql resolvers
2. an empty database (called `empty_test_db`) which we can safely mutate (like inserting and deleting operation) to test seeding functions, among others

So this pull request updates all the scripts and other files for the current tests to work

I have also refactored some of the test scripts to be more readable and also added 
a simple test for testing the `abilityById` graphql query..
  • Loading branch information
mithi committed Oct 31, 2020
2 parents 99b20c5 + f3b1963 commit cf9f177
Show file tree
Hide file tree
Showing 22 changed files with 292 additions and 117 deletions.
3 changes: 2 additions & 1 deletion .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"
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"
56 changes: 33 additions & 23 deletions 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/`.
Expand All @@ -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
Expand All @@ -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!
2 changes: 1 addition & 1 deletion jest.config.js
Expand Up @@ -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)"],
}
15 changes: 14 additions & 1 deletion ormconfig.js
Expand Up @@ -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,
Expand Down
9 changes: 4 additions & 5 deletions package.json
Expand Up @@ -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",
Expand Down
3 changes: 2 additions & 1 deletion 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";
Expand Down
6 changes: 5 additions & 1 deletion 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);
Expand All @@ -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";
2 changes: 1 addition & 1 deletion 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;
Expand Down
18 changes: 15 additions & 3 deletions 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
14 changes: 8 additions & 6 deletions src/services/AbilityService.ts
Expand Up @@ -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)
}
Expand All @@ -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
}
}
4 changes: 3 additions & 1 deletion src/services/BuildSequenceService.ts
Expand Up @@ -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
Expand Down
2 changes: 1 addition & 1 deletion src/services/utils.ts
Expand Up @@ -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
}

Expand Down
35 changes: 35 additions & 0 deletions 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
45 changes: 45 additions & 0 deletions 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())
})

0 comments on commit cf9f177

Please sign in to comment.