Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Frontend/create room #98

Closed
wants to merge 28 commits into from
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 packages/frontend/.eslintignore
Original file line number Diff line number Diff line change
@@ -1,2 +1,3 @@
build
node_modules
cypress
13 changes: 0 additions & 13 deletions packages/frontend/cypress/e2e/APITesting.cy.js

This file was deleted.

46 changes: 46 additions & 0 deletions packages/frontend/cypress/e2e/RoomTest.cy.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
beforeEach(() => {
cy.setupIntercept()
})

describe('Modal E2E Test', () => {
//創建房間成功案例
it('should open modal, input room name, send POST request, and verify response', () => {
cy.visit('http://localhost:3001/rooms')

cy.get('.navbar__btn').click()

// 顯示modal
cy.get('.modal-content').should('be.visible')

// 輸入欄位輸入'一起玩富饒之城'
cy.get('#roomName').type('一起玩富饒之城')

// 按下確認按鈕
cy.get('.blue-btn').click()

// 創建房間POST應該拿到statusOK和200
cy.wait('@createRoomRequest').should(({ request, response }) => {
expect(response.statusCode).to.equal(200)
expect(response.body.status).to.equal('OK')
})
})

it('should handle connection error and display error modal', () => {
//創建房間失敗案例
cy.setupInterceptWithError()

cy.visit('http://localhost:3001/rooms')

cy.get('.navbar__btn').click()

cy.get('.modal-content').should('be.visible')

cy.get('#roomName').type('一起玩富饒之城')

cy.get('.blue-btn').click()

cy.wait('@errorRequest')

cy.get('.error-modal').should('be.visible')
})
})
8 changes: 0 additions & 8 deletions packages/frontend/cypress/e2e/spec.cy.js

This file was deleted.

7 changes: 0 additions & 7 deletions packages/frontend/cypress/e2e/useMockAPI.cy.js
Original file line number Diff line number Diff line change
@@ -1,9 +1,6 @@
// eslint-disable-next-line no-undef
describe('E2E Tests to MockAPI', () => {
// eslint-disable-next-line no-undef
beforeEach(() => {
// 跑E2E測試時,intercept時會攔截XHR、fetch、跨域請求,將get方法呼叫的API改為放在fixtures資料夾的hello.json*
// eslint-disable-next-line no-undef
cy.intercept(
'GET',
'https://001f08b9-acb7-4c3a-a54f-a9254b7e8e55.mock.pstmn.io/get?msg=hello',
Expand All @@ -13,17 +10,13 @@ describe('E2E Tests to MockAPI', () => {
).as('getAPI')
})

// eslint-disable-next-line no-undef
it('should load data from Local Mock API', () => {
// eslint-disable-next-line no-undef
cy.visit('http://localhost:3001/')

// eslint-disable-next-line no-undef
cy.wait('@getAPI', { timeout: 10000 })
.its('response.body')
.then((data) => {
// 在這裡設定預期從API獲取到的數據
// eslint-disable-next-line no-undef
expect(data.args.msg).to.equal('hello')
})
})
Expand Down
20 changes: 20 additions & 0 deletions packages/frontend/cypress/fixtures/createRoom.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
{
"createTime": "2023-07-04T19:29:54.001Z",
"status": "OK",
"msg": "",
"room": {
"roomId": "sxsxs111",
"roomName": "一起玩富饒之城",
"holderId": "player1",
"holderName": "陳XX",
"users": [
{
"userId": "player1",
"userImage": "imageName1",
"userName": "陳XX"
}
],
"status": "OPEN",
"totalUsers": 1
}
}
32 changes: 32 additions & 0 deletions packages/frontend/cypress/support/commands.js
Original file line number Diff line number Diff line change
Expand Up @@ -23,3 +23,35 @@
//
// -- This will overwrite an existing command --
// Cypress.Commands.overwrite('visit', (originalFn, url, options) => { ... })

//POST成功API
Cypress.Commands.add('setupIntercept', () => {
cy.intercept(
'POST',
'https://001f08b9-acb7-4c3a-a54f-a9254b7e8e55.mock.pstmn.io/createroom',
(req) => {
req.body = {
roomName: '一起玩富饒之城',
userName: '陳XX',
userImage: 'imageName1'
}
req.reply({
fixture: 'createRoom.json'
})
}
).as('createRoomRequest')
})

//POST失敗API
Cypress.Commands.add('setupInterceptWithError', () => {
cy.intercept(
'POST',
'https://001f08b9-acb7-4c3a-a54f-a9254b7e8e55.mock.pstmn.io/createroom',
(req) => {
req.reply({
statusCode: 500, // Simulate a server error
body: 'Error occurred'
})
}
).as('errorRequest')
})
19 changes: 19 additions & 0 deletions packages/frontend/js/api/index.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
import axiosInstance from '../common/axiosInstance'

const url =
process.env.NODE_ENV === 'development'
? 'https://001f08b9-acb7-4c3a-a54f-a9254b7e8e55.mock.pstmn.io'
: ''
const axios = axiosInstance(url)

export const getRoomList = (payload) => {
return axios.get('/games', payload)
}

export const createRoom = (payload) => {
return axios.post('/createroom', payload)
}

export const getSpecificRoom = (payload) => {
return axios.get('/rooms', payload)
}
26 changes: 26 additions & 0 deletions packages/frontend/js/common/axiosInstance.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
import axios from 'axios'

export default (baseUrl) => {
const instance = axios.create({
baseURL: baseUrl
})
instance.interceptors.response.use(
(res) => {
if (res && res.status === 200) {
return res.data
}
},
(error) => {
if (error.response) {
switch (error.response.status) {
case 404:
break
default:
console.log(error.message)
}
}
return Promise.reject(error)
}
)
return instance
}
10 changes: 9 additions & 1 deletion packages/frontend/js/components/App.jsx
Original file line number Diff line number Diff line change
@@ -1,10 +1,18 @@
import { Routes, Route, Navigate } from 'react-router-dom'
import RoomList from './RoomList'
import Game from './Game'
import getAPI from '../api/getAPI'

const App = () => {
const { data } = getAPI()
return (
<>
<div>title:{data.msg}</div>
{/* <div>title:{data.msg}</div> */}
<Routes>
<Route path='/' element={<Navigate to='/rooms' />} />
<Route path='/rooms' element={<RoomList />} />
<Route path='/game/:roomId' element={<Game />} />
</Routes>
</>
)
}
Expand Down
28 changes: 28 additions & 0 deletions packages/frontend/js/components/ErrorModal.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
import React from 'react'
import PropTypes from 'prop-types'

const ErrorModal = (props) => {
const { isErrorVisible, onClose, errorText } = props
return (
<>
{isErrorVisible && (
<div className='error-modal'>
<div className='error-modal-content'>
<span className='error-text'>{errorText}</span>
<button className='cancel-btn' onClick={onClose}>
Close
</button>
</div>
</div>
)}
</>
)
}

ErrorModal.propTypes = {
isErrorVisible: PropTypes.bool.isRequired,
onClose: PropTypes.func.isRequired,
errorText: PropTypes.node.isRequired
}

export default ErrorModal
Loading