diff --git a/src/__tests__/RiskInsert.test.js b/src/__tests__/RiskInsert.test.js new file mode 100644 index 0000000..7ca36e8 --- /dev/null +++ b/src/__tests__/RiskInsert.test.js @@ -0,0 +1,55 @@ +const { ObjectId } = require('mongodb'); +const { createRiskGame } = require('../database-scripts/Risk/RiskInsert'); +const { connectToDatabase } = require('../mongoConnection'); + +// Mock MongoDB client and collection +jest.mock('../mongoConnection', () => ({ + connectToDatabase: jest.fn(), + client: { + db: jest.fn(() => ({ + collection: jest.fn(() => ({ + findOne: jest.fn(), + deleteOne: jest.fn(), + insertOne: jest.fn(() => ({ + insertedId: 'some-id' // Replace 'some-id' with an ObjectId string + })), + updateOne: jest.fn() // Mock the updateOne method + })), + })), + close: jest.fn(), + }, + })); + +describe('createRiskGame', () => { + let userData, gameInfo; + + beforeEach(() => { + let mockUserId = '507f191e810c19729de860ea'; // A valid ObjectId string + userData = { + _id: mockUserId, + games_played: 0, + balance: 100, + }; + gameInfo = { + gameMode: 'Local', + playerNames: ['Player 1', 'Player 2'], + players: [ + { name: 'Player 1', armies: 10 }, + { name: 'Player 2', armies: 10 }, + ], + }; + }); + + afterEach(() => { + jest.clearAllMocks(); + }); + + it('should create a new Risk game', async () => { + await createRiskGame(userData, gameInfo); + expect(connectToDatabase).toHaveBeenCalledTimes(2); + expect(connectToDatabase).toHaveBeenCalledWith(); + // Add more expectations as needed + }); + + // Add more test cases as needed +}); diff --git a/src/__tests__/RiskUpdate.test.js b/src/__tests__/RiskUpdate.test.js new file mode 100644 index 0000000..120fb4a --- /dev/null +++ b/src/__tests__/RiskUpdate.test.js @@ -0,0 +1,64 @@ +const { updateRiskGame } = require('../database-scripts/Risk/RiskUpdate'); +const { connectToDatabase } = require('../mongoConnection'); + +jest.mock('../mongoConnection', () => ({ + connectToDatabase: jest.fn(), + client: { + db: jest.fn(() => ({ + collection: jest.fn(() => ({ + updateOne: jest.fn() + })) + })), + close: jest.fn() + } +})); + +describe('updateRiskGame', () => { + afterEach(() => { + jest.clearAllMocks(); + }); + + it('should update local risk game information', async () => { +// Mock data +const gameData = { + _id: '507f191e810c19729de860ea', // Replace with a valid ObjectId string + game_mode: 'Local', + playerNames: ['Player 1', 'Player 2'], + players: [ + { name: 'Player 1', armies: 10 }, + { name: 'Player 2', armies: 10 }, + ], + territories: [ + { name: 'Alaska', owner: null, armies: 3 }, + // Add other territories as needed + ], + player_turn: 'Player 1', // Assuming Player 1 is the first player + winner: null, + game_phase: 'reinforcement', + control: [ + { + region: 'North America', + connections: [ + // Add connections as needed + ], + owner: null + }, + // Add other continents as needed + ], + Cards: [], // Assuming an empty array for cards + created_at: new Date(), + updated_at: new Date() + }; + + // Call the function + await updateRiskGame(gameData); + + // Assertions + expect(connectToDatabase).toHaveBeenCalledTimes(1); + expect(connectToDatabase).toHaveBeenCalledWith(); + + // Add more expectations as needed + }); + + // Add more test cases as needed +}); diff --git a/src/__tests__/UserInsert.test.js b/src/__tests__/UserInsert.test.js new file mode 100644 index 0000000..439dca9 --- /dev/null +++ b/src/__tests__/UserInsert.test.js @@ -0,0 +1,39 @@ +const { createUser } = require('../database-scripts/User/UserInsert'); +const { connectToDatabase } = require('../mongoConnection'); + +jest.mock('../mongoConnection', () => ({ + connectToDatabase: jest.fn(), + client: { + db: jest.fn(() => ({ + collection: jest.fn(() => ({ + insertOne: jest.fn() + })) + })), + close: jest.fn() + } +})); + +describe('createUser', () => { + afterEach(() => { + jest.clearAllMocks(); + }); + + it('should create a new user', async () => { + // Mock data + const userName = 'testUser'; + const password = 'testPassword'; + const email = 'test@example.com'; + const avatar = 'avatar.jpg'; + + // Call the function + await createUser(userName, password, email, avatar); + + // Assertions + expect(connectToDatabase).toHaveBeenCalledTimes(1); + expect(connectToDatabase).toHaveBeenCalledWith(); + + // Add more expectations as needed + }); + + // Add more test cases as needed +}); diff --git a/src/__tests__/rules_test.js b/src/__tests__/rules_test.js new file mode 100644 index 0000000..85cb060 --- /dev/null +++ b/src/__tests__/rules_test.js @@ -0,0 +1,70 @@ +// tests/unit/test_functions.js + +// Import the functions to test +const { getPlayerIndexByName, getCardIndexByName } = require('C:/Users/nesze/CS320/cs320-project/src/html/scripts/gamez/Risk/Risk_rules.js').getPlayerIndexByName; + +// Mock gameData for testing +const gameData = { + players: [ + { name: "Alice" }, + { name: "Bob" }, + { name: "Charlie" } + ], + Cards: [ + { territory: { name: "Card1" } }, + { territory: { name: "Card2" } }, + { territory: { name: "Card3" } } + ] +}; + + +// Define a simple assert function to check conditions +function assert(condition, message) { + if (!condition) { + throw new Error(message); + } +} + +// Test cases for getPlayerIndexByName +function testGetPlayerIndexByName() { + // Test case 1: Finds the index of an existing player by name + assert(getPlayerIndexByName("Bob", gameData) === 1, "Test case 1 failed"); + + // Test case 2: Returns -1 when player with given name is not found + assert(getPlayerIndexByName("David", gameData) === -1, "Test case 2 failed"); + + // Test case 3: Returns -1 when gameData.players is empty + const emptyGameData = { players: [] }; + assert(getPlayerIndexByName("Alice", emptyGameData) === -1, "Test case 3 failed"); + + // Test case 4: Returns -1 when playerName is not a string + assert(getPlayerIndexByName(123, gameData) === -1, "Test case 4 failed"); + + // Add more test cases for getPlayerIndexByName as needed +} + +function testGetCardIndexByName() { + // Test case 1: Finds the index of an existing card by name + assert(getCardIndexByName("Card2", gameData) === 1, "Test case 1 failed"); + + // Test case 2: Returns -1 when card with given name is not found + assert(getCardIndexByName("Card4", gameData) === -1, "Test case 2 failed"); + + // Test case 3: Returns -1 when gameData.Cards is empty + const emptyGameData = { Cards: [] }; + assert(getCardIndexByName("Card1", emptyGameData) === -1, "Test case 3 failed"); + + // Test case 4: Returns -1 when gainedCard is not a string + assert(getCardIndexByName(123, gameData) === -1, "Test case 4 failed"); + + // Add more test cases as needed +} + +// Run all tests +function runAllTests() { + testGetPlayerIndexByName(); + testGetCardIndexByName(); +} + +// Run all tests +runAllTests(); diff --git a/src/app.js b/src/app.js index 5b0f209..923f7a1 100644 --- a/src/app.js +++ b/src/app.js @@ -214,6 +214,41 @@ const server = http.createServer((req, res) => { filePath = path.join(__dirname, 'index.html'); } + if(req.method == 'POST' && req.url === '/submit'){ + console.log('Handling POST request for /bugz.html'); + let data = ''; + + // Collect data from the request + req.on('data', (chunk) => { + console.log('Data chunk received:', chunk); + data += chunk; + }); + + // Process the collected data when the request ends + req.on('end', async () => { + try { + // Parse the form data + console.log('Received form data:', data); + const formData = querystring.parse(data); + console.log('Parsed form data:', formData); + + // Now 'formData' will contain the user input + const Bug = formData.bugTitle; + const detail = formData.bugDescription; + + // Move MongoDB operations here + await createUser(Bug, detail); // make handle for bugpg + + // Respond to the client + res.end('Bug submitted successfully!'); + } catch (error) { + console.error('Error processing form data:', error); + res.end('Internal Server Error'); + } + }); + return; + } + // Check if the requested file is within the html directory if (filePath.indexOf(__dirname) !== 0) { res.writeHead(403); diff --git a/src/chess/chess.js b/src/chess/chess.js index 7e85a7c..ff22bab 100644 --- a/src/chess/chess.js +++ b/src/chess/chess.js @@ -284,6 +284,38 @@ function knight_legality(piece, fcol, frow, tocol, torow, occupation, color) { function king_legality(piece, fcol, frow, tocol, torow, occupation, color) { let move = false; + if (color == "white") { + //short castle + if (piece.first_move && tocol - fcol == 2 && frow == torow) { + if (is_occupied(get_square("g1")) == "empty" + && is_occupied(get_square("f1")) == "empty" + && get_square("h1").children[0].first_move) { + move = true; + } + } else if (piece.first_move && fcol - tocol == 3 && frow == torow) { + if (is_occupied(get_square("b1")) == "empty" + && is_occupied(get_square("c1")) == "empty" + && is_occupied(get_square("d1")) == "empty" + && get_square("a1").children[0].first_move) { + move = true; + } + } + } else if (color == "black") { + if (piece.first_move && tocol - fcol == 2 && frow == torow) { + if (is_occupied(get_square("g8")) == "empty" + && is_occupied(get_square("f8")) == "empty" + && get_square("h8").children[0].first_move) { + move = true; + } + } else if (piece.first_move && fcol - tocol == 3 && frow == torow) { + if (is_occupied(get_square("b8")) == "empty" + && is_occupied(get_square("c8")) == "empty" + && is_occupied(get_square("d8")) == "empty" + && get_square("a8").children[0].first_move) { + move = true; + } + } + } if(color != occupation) { //vertical if(tocol == fcol) @@ -327,7 +359,7 @@ function is_legal_move(piece, destination) { return false; } -function move_piece(from_square, to_square) { +function move_piece(from_square, to_square, is_special_move) { const piece = get_square(from_square).children[0]; const destination = get_square(to_square); const destination_id = destination.id; @@ -355,30 +387,49 @@ function move_piece(from_square, to_square) { else if (color == "black" && destination_id[1] == '1') pawn_promote(piece); } else if (piece.classList.contains("king")) { + //castling + if (color == "white" && piece.first_move) { + if (destination_id == "b1") { + move_piece("a1", "c1", true); + } else if (destination_id == "g1") { + move_piece("h1", "f1", true); + } + } else if (color == "black" && piece.first_move) { + if (destination_id == "b8") { + move_piece("a8", "c8", true); + } else if (destination_id == "g8") { + move_piece("h8", "f8", true); + } + } for (let i = 0; i < board_squares.length; i++) if (board_squares[i].classList.contains("check") && is_occupied(board_squares[i]) == "empty") board_squares[i].classList.remove("check"); } + if (is_special_move == false) { + turn = !turn; + history = history + piece.square_id; + history = history + destination_id; + document.getElementById("turn").innerHTML = turn ? "White's Turn | " + history : "Black's Turn | " + history; + } - turn = !turn; - history = history + piece.square_id; - history = history + destination_id; - document.getElementById("turn").innerHTML = turn ? "White's Turn | " + history : "Black's Turn | " + history; /*update the piece's coordinates*/ piece.first_move = false; piece.square_id = destination_id; - - if (is_check("white")) { - check_audio.play(); - if (color == "white") - undo_move(); - } - else if (is_check("black")) { - check_audio.play(); - if (color == "black") - undo_move(); - } - else move_audio.play(); + + if (is_special_move == false) { + if (is_check("white")) { + check_audio.play(); + if (color == "white") + undo_move(); + } + else if (is_check("black")) { + check_audio.play(); + if (color == "black") + undo_move(); + } + else move_audio.play(); + } else capture_audio.play(); + } /*main movement functions*/ @@ -408,7 +459,7 @@ function drop(ev) { if (!is_legal_move(piece, destination)) return; - move_piece(piece.square_id, destination_id); + move_piece(piece.square_id, destination_id, false); } /*setup*/ @@ -454,10 +505,9 @@ async function play_board(moves, main_board) { for (let i = 0; i < moves.length; i = i+4) { let from = moves[i] + moves[i+1]; let to = moves[i+2] + moves[i+3]; - move_piece(from, to, main_board); + move_piece(from, to, false); if (main_board) await delay(300); } - //reset_board(); } function undo_move() { @@ -465,10 +515,14 @@ function undo_move() { reset_board(); history = ""; play_board(temp, false); - turn = !turn; + //turn = !turn; + clone_board(); + clone_pieces(); } -let temp = "f2f4e7e5e2e3f7f6f4e5g8h6e5f6f8b4f6g7d8e7"; +let temp = ""; +//let temp = "f2f4e7e5e2e3f7f6f4e5g8h6e5f6f8b4f6g7d8e7"; //pawn promote +//let temp = "g2g4e7e6f2f3d7d5f1h3b8a6f3f4c7c6g1f3c8d7b1a3g8h6c2c3f8d6d2d3d8g5c1e3c6c5d1c2b7b6"; //castling init_board(); init_pieces(); diff --git a/src/database-scripts/Bugs/BugInsert.js b/src/database-scripts/Bugs/BugInsert.js new file mode 100644 index 0000000..e9cf452 --- /dev/null +++ b/src/database-scripts/Bugs/BugInsert.js @@ -0,0 +1,36 @@ +const { connectToDatabase, client } = require('../../mongoConnection'); +const { ObjectId } = require('mongodb'); + +// Function to create a new User +async function createBug(Bug, detail, mailBack) { + try { + // Connect to MongoDB + await connectToDatabase(); + + // Get reference to the database + const db = client.db(); + + // Create a new user object + const newBug = { + _id: new ObjectId(), + Title: Bug, + Description: detail, + Mail_Back: mailBack + }; + + // Insert the new user into the UserInformation collection + const insert = await db.collection('Bugs').insertOne(newBug); + + console.log(`Bug created with ID: ${insert.insertedId}`); + } + catch (error) { + console.error('Error inserting new bug:', error); + } + finally { + await client.close(); + } +} + +module.exports = { + createBug, +}; diff --git a/src/database-scripts/Risk/RiskInsert.js b/src/database-scripts/Risk/RiskInsert.js index aa849eb..6e93b43 100644 --- a/src/database-scripts/Risk/RiskInsert.js +++ b/src/database-scripts/Risk/RiskInsert.js @@ -164,8 +164,11 @@ async function createRiskGame(userData, gameInfo) { // Insert the new game document into the Risk collection const result = await db.collection('Risk').insertOne(newGame); - if (result && gameInfo.gameMode === 'Computer') { - userData.balance -= 10; + if(result) { + userData.games_played += 1; + if (gameInfo.gameMode === 'Computer') { + userData.balance -= 10; + } await updateUser(userData._id, userData); } console.log(`Risk game created with ID: ${result.insertedId}`); diff --git a/src/database-scripts/User/UserInsert.js b/src/database-scripts/User/UserInsert.js index 05ddf10..55aa390 100644 --- a/src/database-scripts/User/UserInsert.js +++ b/src/database-scripts/User/UserInsert.js @@ -17,7 +17,10 @@ async function createUser(user_name, password, email, avatar) { password: password, email: email, avatar: avatar, - balance: 100 + balance: 100, + wins: 0, + losses: 0, + games_played: 0 }; // Insert the new user into the UserInformation collection diff --git a/src/html/bugz.html b/src/html/bugz.html new file mode 100644 index 0000000..008d5cc --- /dev/null +++ b/src/html/bugz.html @@ -0,0 +1,131 @@ + + + + + + + Bugz Report + + + + + + + + +

Let us know what to improve!

+ +
+ + + + + + + +
+ + + + + + + + + + \ No newline at end of file diff --git a/src/html/cart.html b/src/html/cart.html index 9c1d0b8..6d91844 100644 --- a/src/html/cart.html +++ b/src/html/cart.html @@ -1,84 +1,85 @@ - - - - - Gamez Central - - - - - - - - - - - -
-

Cart

-
-
-
- - -
-
- - - - - - - - - - - - + + + + + Gamez Central + + + + + + + + + + + +
+

Cart

+
+
+
+ + +
+
+ + + + + + + + + + + + diff --git a/src/html/chess.html b/src/html/chess.html index fc51c93..f890d88 100644 --- a/src/html/chess.html +++ b/src/html/chess.html @@ -2,52 +2,57 @@ - Gamez Central - - - + Gamez Central + + + + + + + + - + - + + +
@@ -77,27 +82,42 @@ Repo

- - + - - - + + + + + + + + - + + + diff --git a/src/html/credits.html b/src/html/credits.html index db4cb09..67e46bb 100644 --- a/src/html/credits.html +++ b/src/html/credits.html @@ -1,83 +1,80 @@ - - - - - - - Gamez Central - Credits - - - - - - - -

Gamez Central - Credits

- - -
-
-

Ines C.

-

Role:

-

Brendan H.

-

Role:

-

Ethan S.

-

Role:

-

Jacob R.

-

Role:

-
-
- - - - - - - - - - - + + + + + + + Gamez Central - Credits + + + + + + + +

Gamez Central - Credits

+ + +
+
+

Ines C.

+

Brendan H.

+

Ethan S.

+

Jacob R.

+
+
+ + + + + + + + + + + diff --git a/src/html/leaderboard.html b/src/html/leaderboard.html index 0e4850f..5b78be6 100644 --- a/src/html/leaderboard.html +++ b/src/html/leaderboard.html @@ -1,92 +1,93 @@ - - - - - - - Gamez Central - Leaderboard - - - - - - - -

Gamez Central - Leaderboard

- -
-
- - - - - - - - - - - - - - - -
User NameUser IDBalanceWinsLossesGames Played
-
-
- - - - - - - - - - - - + + + + + + + Gamez Central - Leaderboard + + + + + + + +

Gamez Central - Leaderboard

+ +
+
+ + + + + + + + + + + + + + + +
User NameUser IDBalanceWinsLossesGames Played
+
+
+ + + + + + + + + + + + diff --git a/src/html/login.html b/src/html/login.html index dcc0cca..53850cf 100644 --- a/src/html/login.html +++ b/src/html/login.html @@ -15,6 +15,7 @@ Tic-Tac-Toe Leaderboard Credits + Report Bugs
-
+
@@ -153,17 +155,19 @@

Number of AI Opponents

+
-