-
Notifications
You must be signed in to change notification settings - Fork 56
[클린코드 4기 이철환] 자판기 미션 STEP 1 #61
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
Open
go-lani
wants to merge
44
commits into
next-step:publizm
Choose a base branch
from
go-lani:step1
base: publizm
Could not load branches
Branch not found: {{ refName }}
Loading
Could not load tags
Nothing to show
Loading
Are you sure you want to change the base?
Some commits from the old base branch may be removed from the timeline,
and old review comments may become outdated.
Open
Changes from all commits
Commits
Show all changes
44 commits
Select commit
Hold shift + click to select a range
2e41697
temp: 세팅중
go-lani 6164f6c
style: 상품 관리, 잔돈 충전 영역 UI 구현 및 템플릿화
go-lani 740713a
Merge branch 'setting' into main
go-lani 0f2be8a
fix: html class attribute 오타 수정
go-lani cc0e90e
feat: 아키텍쳐 세팅
go-lani b2ac1ce
feat: initial rendering 구현
go-lani 97f99e3
style: 레이아웃 css 수정
go-lani e3d7715
fix: 메뉴 id 의미에 맞게 수정
go-lani d85f9b9
test: 메뉴 테스트 / 메뉴별 테스트 분리
go-lani a660a76
refactor: View에 대한 부모 클래스 생성 및 상속 적용
go-lani dfea8eb
refactor: 불필요한 View 모델 삭제 및 로직 제거
go-lani 20bf3d0
refactor: Template 관련 변수 리팩토링
go-lani 8ca2084
test: 메뉴 탭 관련 테스트코드 작성 완료
go-lani 6d7be9f
refactor: 메뉴탭 클릭이벤트 validation 로직 수정
go-lani 1d7057a
temp: submit 구현중
go-lani 2fa9f45
test: 상품 관리 테스트 케이스 추가
go-lani d859a21
feat: 상품 추가하기 로직 추가 및 테스트코드 작성
go-lani 6b639e4
feat: 상품 현황 관련 로직 및 테스트 코드 추가
go-lani a5e1764
test: 잔돈 충전 메뉴 테스트 케이스 작성
go-lani 90e5df7
test: 보유 동전 관련 테스트코드 작성
go-lani 72fe279
refactor: input 입력값 타입 변경
go-lani ce25291
refactor: element 변수명 변경
go-lani 86cf9bb
refactor: argument 타입 변경
go-lani 6599d48
refactor: Dom Selector 변수명 컨벤션에 따른 수정
go-lani 1b09fd4
refactor: 상수값 네이밍 유연하게 변경
go-lani c9efa8e
refactor: argument 타입 변경 #2
go-lani a3f069a
feat: 잔돈 충전 기능 구현 및 테스트 코드 추가
go-lani c648c35
style: 코드 정리
go-lani 015f492
feat: localStorage 기능 추가
go-lani a63fc10
feat: 메뉴 관련 localStorage 기능 추가 및 리팩토링
go-lani 0e23cee
Merge pull request #1 from go-lani/step1
go-lani 18ca601
refactor: 테스트 케이스 문구 디테일 수정
go-lani bbee807
refactor: 중복 테스트 케이스 삭제
go-lani d059ffb
refactor: vendinMachine > submitChargerForm 메소드 dom 의존성 제거
go-lani 876a9fd
refactor: 안 쓰는 멤버 제거
go-lani 65473fe
refactor: vendingMachine controller initialize 메소드 추가 및 menuItem 관련 로…
go-lani 792198d
refactor: handlers > submitFormHandlers 범용적인 변수명 수정
go-lani 2eb9189
refactor: validate error 핸들링 수정 및 함수 리팩토링
go-lani b0a216d
refactor: 제품관리 추가 로직 수정 forEach > reduce
go-lani 80fd4fe
refactor: validateMenu 메소드 매개변수명 수정 및 메뉴 여부 체크 로직 수정
go-lani b8fdddc
refactor: 직관적인 변수명으로 변경 changeView > initializeBasedOnChangedMenu
go-lani 9e27779
refactor: clearForm 로직 공용 유틸함수로 분리
go-lani 617e1ee
refactor: view initialize 로직 render와 update 분리
go-lani 3d4b6ed
refactor: view에 대한 의존성 제거 및 view update method 추상화
go-lani File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,23 @@ | ||
{ | ||
"env": { | ||
"browser": true, | ||
"es2022": true, | ||
"node": true | ||
}, | ||
"parserOptions": { | ||
"ecmaVersion": "latest", | ||
"sourceType": "module" | ||
}, | ||
"extends": ["airbnb", "plugin:prettier/recommended", "plugin:cypress/recommended"], | ||
"rules": { | ||
"import/extensions": [ | ||
"off" | ||
], | ||
"max-depth": ["error", 2], | ||
"lines-between-class-members": "off", | ||
"class-methods-use-this": "off", | ||
"import/prefer-default-export": "off", | ||
"no-unused-expressions": "off", | ||
"no-param-reassign": "off" | ||
} | ||
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,107 @@ | ||
# Logs | ||
logs | ||
*.log | ||
npm-debug.log* | ||
yarn-debug.log* | ||
yarn-error.log* | ||
lerna-debug.log* | ||
|
||
# Diagnostic reports (https://nodejs.org/api/report.html) | ||
report.[0-9]*.[0-9]*.[0-9]*.[0-9]*.json | ||
|
||
# Runtime data | ||
pids | ||
*.pid | ||
*.seed | ||
*.pid.lock | ||
|
||
# Directory for instrumented libs generated by jscoverage/JSCover | ||
lib-cov | ||
|
||
# Coverage directory used by tools like istanbul | ||
coverage | ||
*.lcov | ||
|
||
# nyc test coverage | ||
.nyc_output | ||
|
||
# Grunt intermediate storage (https://gruntjs.com/creating-plugins#storing-task-files) | ||
.grunt | ||
|
||
# Bower dependency directory (https://bower.io/) | ||
bower_components | ||
|
||
# node-waf configuration | ||
.lock-wscript | ||
|
||
# Compiled binary addons (https://nodejs.org/api/addons.html) | ||
build/Release | ||
|
||
# Dependency directories | ||
node_modules/ | ||
jspm_packages/ | ||
|
||
# TypeScript v1 declaration files | ||
typings/ | ||
|
||
# TypeScript cache | ||
*.tsbuildinfo | ||
|
||
# Optional npm cache directory | ||
.npm | ||
|
||
# Optional eslint cache | ||
.eslintcache | ||
|
||
# Microbundle cache | ||
.rpt2_cache/ | ||
.rts2_cache_cjs/ | ||
.rts2_cache_es/ | ||
.rts2_cache_umd/ | ||
|
||
# Optional REPL history | ||
.node_repl_history | ||
|
||
# Output of 'npm pack' | ||
*.tgz | ||
|
||
# Yarn Integrity file | ||
.yarn-integrity | ||
|
||
# dotenv environment variables file | ||
.env | ||
.env.test | ||
|
||
# parcel-bundler cache (https://parceljs.org/) | ||
.cache | ||
|
||
# Next.js build output | ||
.next | ||
|
||
# Nuxt.js build / generate output | ||
.nuxt | ||
dist | ||
|
||
# Gatsby files | ||
.cache/ | ||
# Comment in the public line in if your project uses Gatsby and *not* Next.js | ||
# https://nextjs.org/blog/next-9-1#public-directory-support | ||
# public | ||
|
||
# vuepress build output | ||
.vuepress/dist | ||
|
||
# Serverless directories | ||
.serverless/ | ||
|
||
# FuseBox cache | ||
.fusebox/ | ||
|
||
# DynamoDB Local files | ||
.dynamodb/ | ||
|
||
# TernJS port file | ||
.tern-port | ||
|
||
|
||
.idea |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,4 @@ | ||
#!/usr/bin/env sh | ||
. "$(dirname -- "$0")/_/husky.sh" | ||
|
||
npx lint-staged |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,4 @@ | ||
{ | ||
"plugins": ["prettier-plugin-tailwindcss"], | ||
"tailwindConfig": "./tailwind.config.js" | ||
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,6 @@ | ||
// eslint-disable-next-line import/no-extraneous-dependencies | ||
const { defineConfig } = require("cypress"); | ||
|
||
module.exports = defineConfig({ | ||
e2e: {}, | ||
}); |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,144 @@ | ||
import { | ||
CHANGE_CHARGE_MENU_SELECTOR, | ||
CHARGER_INPUT_SELECTOR, | ||
COIN_AMOUNT_SELECTOR, | ||
COIN_CHARGE_BUTTON_SELECTOR, | ||
COIN_CHARGING_FORM_SELECTOR, | ||
COIN_INVENTORY_SELECTOR, | ||
COIN_UNIT_SELECTOR, | ||
HOLDING_AMOUNT_SELECTOR, | ||
PRODUCT_MANAGE_MENU_SELECTOR, | ||
} from "../support/selectors.js"; | ||
import { ERROR_MESSAGE, MINIMUM_CHARGE_PRICE } from "../support/constants"; | ||
import { calculateCoinCount } from "../../src/js/utils/utils.js"; | ||
|
||
describe("잔돈 충전 테스트", () => { | ||
beforeEach(() => { | ||
cy.visit("/"); | ||
cy.get(CHANGE_CHARGE_MENU_SELECTOR).click(); | ||
}); | ||
|
||
context("잔돈 충전을 할 수 있다.", () => { | ||
it("잔돈 충전 입력 폼이 보인다", () => { | ||
cy.get(COIN_CHARGING_FORM_SELECTOR).should("exist"); | ||
}); | ||
|
||
it("잔돈을 입력할 수 있는 Input이 존재한다.", () => { | ||
cy.get(CHARGER_INPUT_SELECTOR).should("exist"); | ||
}); | ||
|
||
it("최초 보유한 금액은 0원이다", () => { | ||
cy.get(HOLDING_AMOUNT_SELECTOR).should("have.text", "0"); | ||
}); | ||
|
||
it("100원부터 충전이 가능하며 잘못 입력시 alert가 뜬다", () => { | ||
cy.alert({ | ||
action: () => { | ||
cy.get(CHARGER_INPUT_SELECTOR).type("50"); | ||
return cy.get(COIN_CHARGE_BUTTON_SELECTOR).click(); | ||
}, | ||
message: ERROR_MESSAGE.INVALID_AMOUNT, | ||
}); | ||
}); | ||
|
||
it("잔돈은 10원 단위로 충전이 가능하며 잘못된 값을 충전시 alert가 뜬다", () => { | ||
cy.alert({ | ||
action: () => { | ||
cy.get(CHARGER_INPUT_SELECTOR).type("101"); | ||
return cy.get(COIN_CHARGE_BUTTON_SELECTOR).click(); | ||
}, | ||
message: ERROR_MESSAGE.INVALID_UNIT, | ||
}); | ||
}); | ||
|
||
it("잔돈 입력 후 Enter키를 눌러서 충전할 수 있다", () => { | ||
cy.get(CHARGER_INPUT_SELECTOR).type(`${MINIMUM_CHARGE_PRICE}{enter}`); | ||
cy.get(HOLDING_AMOUNT_SELECTOR).should("have.text", MINIMUM_CHARGE_PRICE); | ||
}); | ||
|
||
it("잔돈 입력후 충전하기 버튼을 눌러서 충전할 수 있다", () => { | ||
cy.get(CHARGER_INPUT_SELECTOR).type(String(MINIMUM_CHARGE_PRICE)); | ||
|
||
cy.get(COIN_CHARGE_BUTTON_SELECTOR) | ||
.click() | ||
.then(() => { | ||
cy.get(HOLDING_AMOUNT_SELECTOR).should( | ||
"have.text", | ||
MINIMUM_CHARGE_PRICE | ||
); | ||
}); | ||
}); | ||
|
||
it("잔돈은 누적하여 충전할 수 있다", () => { | ||
const FIRST_CHARGE = MINIMUM_CHARGE_PRICE; | ||
const SECOND_CHARGE = MINIMUM_CHARGE_PRICE * 2; | ||
|
||
cy.get(CHARGER_INPUT_SELECTOR).type(String(FIRST_CHARGE)); | ||
cy.get(COIN_CHARGE_BUTTON_SELECTOR).click(); | ||
|
||
cy.get(CHARGER_INPUT_SELECTOR).type(String(SECOND_CHARGE)); | ||
cy.get(COIN_CHARGE_BUTTON_SELECTOR).click(); | ||
|
||
cy.get(HOLDING_AMOUNT_SELECTOR).should( | ||
"have.text", | ||
String(FIRST_CHARGE + SECOND_CHARGE) | ||
); | ||
}); | ||
}); | ||
|
||
context("보유한 동전을 갯수를 확인할 수 있다.", () => { | ||
it("잔돈 현황을 확인할 수 있는 테이블이 보인다", () => { | ||
cy.get(COIN_INVENTORY_SELECTOR).should("exist"); | ||
}); | ||
|
||
it("최초 보유한 동전의 갯수는 각각 0개이다", () => { | ||
cy.get(COIN_AMOUNT_SELECTOR).each((amount) => { | ||
expect(amount).text("0개"); | ||
}); | ||
}); | ||
|
||
it("500원, 100원, 50원, 10원 단위에 따른 동전의 갯수로 표시된다", () => { | ||
const coinUnit = ["500", "100", "50", "10"]; | ||
cy.get(COIN_UNIT_SELECTOR).each((unit, index) => { | ||
expect(unit).text(coinUnit[index]); | ||
}); | ||
}); | ||
|
||
it("보유한 동전은 X개 형식으로 확인할 수 있다", () => { | ||
const charge = 1000; | ||
cy.get(CHARGER_INPUT_SELECTOR).type(`${charge}{enter}`); | ||
const result = calculateCoinCount(charge); | ||
|
||
cy.get(COIN_AMOUNT_SELECTOR).each((amount) => { | ||
const id = amount.closest("tr").attr("id"); | ||
const unit = id.replace("coin-", ""); | ||
|
||
expect(amount).text(`${result[unit]}개`); | ||
}); | ||
}); | ||
}); | ||
|
||
it("다른 메뉴로 이동 후 다시 돌아왔을 경우 값은 유지된다.", () => { | ||
const charge = 1000; | ||
cy.get(CHARGER_INPUT_SELECTOR).type(`${charge}{enter}`); | ||
const result = calculateCoinCount(charge); | ||
|
||
cy.get(COIN_AMOUNT_SELECTOR).each((amount) => { | ||
const id = amount.closest("tr").attr("id"); | ||
const unit = id.replace("coin-", ""); | ||
|
||
expect(amount).text(`${result[unit]}개`); | ||
}); | ||
|
||
cy.get(PRODUCT_MANAGE_MENU_SELECTOR).click(); | ||
|
||
cy.get(CHANGE_CHARGE_MENU_SELECTOR).click(); | ||
|
||
cy.get(COIN_AMOUNT_SELECTOR).each((amount) => { | ||
const id = amount.closest("tr").attr("id"); | ||
const unit = id.replace("coin-", ""); | ||
|
||
expect(amount).text(`${result[unit]}개`); | ||
}); | ||
}); | ||
}); |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,56 @@ | ||
import { | ||
CHANGE_CHARGE_MENU_SELECTOR, | ||
COIN_CHARGING_CONTAINER_SELECTOR, | ||
MENU_SELECTOR, | ||
PRODUCT_MANAGE_MENU_SELECTOR, | ||
PRODUCT_MANAGER_CONTAINER_SELECTOR, | ||
PRODUCT_PURCHASE_CONTAINER_SELECTOR, | ||
PRODUCT_PURCHASE_MENU_SELECTOR, | ||
} from "../support/selectors.js"; | ||
|
||
describe("메뉴 탭 UI 테스트", () => { | ||
beforeEach(() => { | ||
cy.visit("/"); | ||
}); | ||
it("메뉴 탭 리스트 UI가 화면에 존재한다.", () => { | ||
cy.get(MENU_SELECTOR).should("exist"); | ||
}); | ||
|
||
it("메뉴는 상품 관리, 잔돈 충전, 상품 구매가 있다.", () => { | ||
cy.get(`${MENU_SELECTOR} button`).should(($menuButton) => { | ||
expect($menuButton).to.have.length(3); | ||
|
||
const menuTexts = $menuButton.map((_, el) => el.innerText); | ||
|
||
expect(menuTexts.get()).to.deep.equal([ | ||
"상품 관리", | ||
"잔돈 충전", | ||
"상품 구매", | ||
]); | ||
}); | ||
}); | ||
|
||
context("각 메뉴 클릭시 해당 메뉴화면이 노출된다.", () => { | ||
it("잔돈 충전 메뉴 클릭시 해당 화면이 노출된다.", () => { | ||
cy.get(CHANGE_CHARGE_MENU_SELECTOR) | ||
.click() | ||
.then(() => { | ||
cy.get(COIN_CHARGING_CONTAINER_SELECTOR).should("exist"); | ||
}); | ||
}); | ||
it("상품 구매 메뉴 클릭시 해당 화면이 노출된다.", () => { | ||
cy.get(PRODUCT_PURCHASE_MENU_SELECTOR) | ||
.click() | ||
.then(() => { | ||
cy.get(PRODUCT_PURCHASE_CONTAINER_SELECTOR).should("exist"); | ||
}); | ||
}); | ||
it("상품 관리 메뉴 클릭시 해당 화면이 노출된다.", () => { | ||
cy.get(PRODUCT_MANAGE_MENU_SELECTOR) | ||
.click() | ||
.then(() => { | ||
cy.get(PRODUCT_MANAGER_CONTAINER_SELECTOR).should("exist"); | ||
}); | ||
}); | ||
}); | ||
}); |
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
(마이너 코멘트)
String으로 캐스팅 안해도 type 메서드를 거치면 알아서 string으로 들어갈겁니다.
input value는 항상 string이니까요!
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@Tanney-102 공식 문서에 type 메소드의 argument로 string 값을 받는 걸로 표기되어 있고, IDE에서 경고를 줘서 String 생성자 함수로 강제 변환을 시켰습니다!

혹시 type에서 number 타입으로 입력되더라도 string 값으로 타입변환이 되는걸까요?? 별도로 문구가 안보여가지구요!
Cypress type Link
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
피드백 후 반영하도록 하겠습니다!