Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions IT2810
4 changes: 2 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -13,9 +13,9 @@ The current implementation includes:
- A MariaDB database containing Pokémon data.
- A GraphQL API built with Node.js, TypeScript, and Apollo Server.
- GraphQL queries for retrieving lists of Pokémon and individual Pokémon by ID.
- A React frontend using Apollo Client to retrieve and display Pokémon.
- A React frontend using Apollo Client to search for Pokémon and build a team.

The frontend currently displays a list of Pokémon. Search, team building, and other planned features are not yet fully implemented.
The frontend displays search results and team members as Pokémon cards with sprites, names and types. Further features such as stats overviews are still under development.

## Dataset

Expand Down
5 changes: 4 additions & 1 deletion backend/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -78,11 +78,12 @@ query {
id
name
type
sprite
}
}
```

This query returns Pokémon records with their IDs, names and types.
This query returns Pokémon records with their IDs, names, types and sprite file names. `sprite` is the file name in `SPRITES_DIR`, or `null` when no sprite exists.

### Retrieve a Pokémon by ID

Expand All @@ -92,6 +93,7 @@ query {
id
name
type
sprite
}
}
```
Expand Down Expand Up @@ -150,6 +152,7 @@ The tests use `http://localhost:3001/` by default. To test another endpoint, set

- Retrieving the Pokémon list
- Retrieving a Pokémon by ID
- Retrieving a Pokémon's sprite file name
- Returning `null` for an unknown Pokémon ID
- Rejecting a query containing an invalid GraphQL field

Expand Down
20 changes: 20 additions & 0 deletions backend/src/graphql/api.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -104,6 +104,26 @@ describe("GraphQL API integration", () => {
expect(body.data?.pokemon).toEqual(firstPokemon);
});

it("returns the sprite file name for a Pokémon", async () => {
const { response, body } = await sendQuery<{
pokemon: { id: string; sprite: string | null } | null;
}>(
`
query GetPokemon($id: ID!) {
pokemon(id: $id) {
id
sprite
}
}
`,
{ id: "bulbasaur" },
);

expect(response.status).toBe(200);
expect(body.errors).toBeUndefined();
expect(body.data?.pokemon?.sprite).toBe("bulbasaur.png");
});

it("returns null for an unknown Pokémon ID", async () => {
const { response, body } = await sendQuery<{
pokemon: Pokemon | null;
Expand Down
10 changes: 7 additions & 3 deletions backend/src/graphql/resolvers.ts
Original file line number Diff line number Diff line change
Expand Up @@ -47,14 +47,15 @@ export const resolvers = {
`SELECT
p.id,
p.name,
p.sprite,
COALESCE(
GROUP_CONCAT(t.name ORDER BY pt.slot SEPARATOR ', '),
''
) AS type
FROM pokemon p
LEFT JOIN pokemon_types pt ON pt.pokemon_id = p.id
LEFT JOIN types t ON t.id = pt.type_id
GROUP BY p.id, p.name
GROUP BY p.id, p.name, p.sprite
ORDER BY p.num, p.name`,
);

Expand All @@ -66,6 +67,7 @@ export const resolvers = {
`SELECT
p.id,
p.name,
p.sprite,
COALESCE(
GROUP_CONCAT(t.name ORDER BY pt.slot SEPARATOR ', '),
''
Expand All @@ -74,14 +76,15 @@ export const resolvers = {
LEFT JOIN pokemon_types pt ON pt.pokemon_id = p.id
LEFT JOIN types t ON t.id = pt.type_id
WHERE p.id = ?
GROUP BY p.id, p.name`,
GROUP BY p.id, p.name, p.sprite`,
[id],
);

const pokemonRows = rows as {
id: string;
name: string;
type: string;
sprite: string | null;
}[];

return pokemonRows[0] ?? null;
Expand Down Expand Up @@ -189,6 +192,7 @@ export const resolvers = {
p.name,
p.gen,
p.num,
p.sprite,
COALESCE(
GROUP_CONCAT(t.name ORDER BY pt.slot SEPARATOR ', '),
''
Expand All @@ -197,7 +201,7 @@ export const resolvers = {
LEFT JOIN pokemon_types pt ON pt.pokemon_id = p.id
LEFT JOIN types t ON t.id = pt.type_id
WHERE ${conditions.join(" AND ")}
GROUP BY p.id, p.name, p.gen, p.num
GROUP BY p.id, p.name, p.gen, p.num, p.sprite
ORDER BY ${orderBy}
LIMIT ? OFFSET ?`,
[...parameters, limit, offset],
Expand Down
2 changes: 2 additions & 0 deletions backend/src/graphql/schema.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ export const typeDefs = `#graphql
id: ID!
name: String!
type: String!
sprite: String
}
type PokemonSearchResult {
Expand All @@ -11,6 +12,7 @@ export const typeDefs = `#graphql
type: String!
gen: Int!
num: Int!
sprite: String
}
type TypeEffectiveness {
Expand Down
Loading