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

[3단계 - 행운의 로또 미션] 지그(송지은) 미션 제출합니다. #64

Merged
merged 36 commits into from
Mar 2, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
36 commits
Select commit Hold shift + click to select a range
6385769
[1단계 - 행운의 로또 미션] 티케(조은현) 미션 제출합니다 (#26)
devhyun637 Feb 20, 2021
1be66e6
Merge branch 'zigsong' of https://github.com/woowacourse/javascript-l…
zigsong Feb 28, 2021
71cb30a
docs: make step3 todos
zigsong Feb 25, 2021
f731765
test: show purchase-type select butons
zigsong Feb 25, 2021
398fb2d
feat: show purchase-type select butons
zigsong Feb 25, 2021
cdca062
refactor: rename lotto-input-nums to lotto-winning-nums
zigsong Feb 25, 2021
8daa689
test: switch purchase-type button color
zigsong Feb 25, 2021
45e24fe
feat: switch purchase-type button
zigsong Feb 25, 2021
472a630
test: show manual input form when choose manual purchase
zigsong Feb 26, 2021
e3920bd
refactor: rename dom to selector
zigsong Feb 26, 2021
08ca044
feat: show manual input form when choose manual purchase
zigsong Feb 26, 2021
e1fef16
test: alert when type duplicate numbers in manual input
zigsong Feb 26, 2021
7823ca7
feat: alert when type duplicate numbers in manual input
zigsong Feb 26, 2021
9607d94
test: show confirmed lotto ticket if typed manul numbers correctly
zigsong Feb 27, 2021
da9f3d5
feat: create & show confirmed lotto ticket if typed manul numbers cor…
zigsong Feb 27, 2021
f311083
test: show confirm alert when manual input count is lesser than price
zigsong Feb 27, 2021
b928fd3
feat: show confirm alert when manual input count is lesser than price
zigsong Feb 27, 2021
9b04090
test: process auto purchase when agree to auto purchase confirm
zigsong Feb 27, 2021
b1238d5
feat: process auto purchase when agree to auto purchase confirm
zigsong Feb 27, 2021
64aa134
fix: remove wrong classname and unnecessary index
zigsong Feb 27, 2021
8728c0f
feat: process manual purchase when typed all manual inputs
zigsong Feb 27, 2021
dd3f2ab
fix: fix bugs when switching between auto/manual purchase
zigsong Feb 28, 2021
6329e9d
fix: resolve conflicts with step2 merge commit
zigsong Feb 28, 2021
cecda97
refactor: update getRandomNumber logic
zigsong Feb 28, 2021
d6a3dc2
refactor: remove unnecessary classnames & add lotto number constant
zigsong Feb 28, 2021
910947d
refactor: typos in cypress
zigsong Feb 28, 2021
60f0ba5
feat: add auto-convert caption in manual input view
zigsong Feb 28, 2021
62aaf02
feat: move focus to next input in manual input view
zigsong Feb 28, 2021
3682f7e
refactor:
zigsong Mar 1, 2021
f7858e1
refactor:
zigsong Mar 1, 2021
964f5e6
fix: fix binding events bug on manualInputView
zigsong Mar 1, 2021
18d57c1
refactor: update array loop logic in manualInputView
zigsong Mar 1, 2021
b6db430
refactor: separate method checking if last number input (prevent movi…
zigsong Mar 1, 2021
8afe5e5
refactor: update showAllConfirmButton logic
zigsong Mar 1, 2021
f98aa76
refactor:
zigsong Mar 1, 2021
043299b
fix: reset to autoPurchase when click restart in manual purchase step
zigsong Mar 1, 2021
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
27 changes: 27 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -113,6 +113,33 @@
- [ ] 수동 구매 후 남는 금액이 있다면 자동으로 구매할 수 있어야 한다.
- [ ] 위 기능들이 정상적으로 동작하는지 Cypress를 이용해 테스트한다.

### ✅ 3단계 미션 TODO

**기능**
- [x] 수동 구매, 자동 구매 선택지 UI 만들기
- [x] 수동 구매, 자동 구매 선택지 중 현재 선택 옵션 하이라트
- [x] 수동 구매 선택 시, 번호 입력 폼 UI 만들기
- [x] 소비자가 입력한 수동 구매 번호 저장하기
- [x] 검증: 번호는 1~45 사이의 숫자만 가능하다.
- [x] 검증: 로또 한 장에 중복된 번호가 없어야 한다.
- [x] 수동 구매 후 남는 금액이 있다면 자동 구매를 진행한다는 확인창 띄우기
- [x] 자동 구매 취소 시 계속해서 수동 구매 번호 입력 폼 채우기
- [x] 자동 구매 동의 시 남는 금액으로 자동 구매 진행하기
- [x] 소비자가 구매한 로또로 당첨 결과를 계산하여 모달에 보여주기

**테스트**
- [x] 수동 구매, 자동 구매 선택지를 보여준다.
- [x] 수동 구매, 자동 구매 선택지 중 현재 선택 옵션을 표시한다.
- [x] 수동 구매를 선택하고 금액을 입력하면, 금액만큼의 번호 입력 폼을 보여준다.
- ~~[ ] 검증: 1~45 사이의 숫자 입력 시 알럿이 뜬다.~~
- [x] 검증: 로또 한 장에 중복된 번호 입력 시 알럿이 뜬다.
- [x] 수동 구매 번호를 모두 올바르게 입력하면, 확정된 로또 티켓을 보여준다.
- [x] 수동 구매 후 남는 금액 발생 시 자동 구매 진행 확인창이 뜬다.
- ~~[ ] 자동 구매 취소 시 계속해서 수동 구매 번호 입력 폼을 채울 수 있다.~~
- [x] 자동 구매 동의 시 자동구매를 진행한다.
- [x] 소비자가 구매한 로또의 당첨 결과가 모달에 올바르게 표시된다.


<br>

## ⚙️ Before Started
Expand Down
137 changes: 111 additions & 26 deletions cypress/integration/lottoTest/lottoTest.spec.js
Original file line number Diff line number Diff line change
@@ -1,13 +1,14 @@
import { getRandomNumber } from '../../../src/js/utils/utils.js';
import LottoProcessor from '../../../src/js/utils/lottoProcessor.js';
import { LOTTO_NUMBERS } from '../../../src/js/utils/constants.js';
import Lotto from '../../../src/js/Lotto.js';

describe('로또 게임 테스트', () => {
beforeEach(() => {
cy.visit('http://127.0.0.1:5500/');
});

const price = 10000;
const price = 5000;
const lottoTotalCount = price / 1000;
const LOTT0_LENGTH = 7;

Expand All @@ -16,30 +17,116 @@ describe('로또 게임 테스트', () => {
cy.get('#input-price-btn').click();
}

function typeManualNumberAndConfirm() {
cy.get('.manual-wrapper').each(manualTicket => {
cy.wrap(manualTicket)
.find('.manual-number')
.each((manualNumber, innerIdx) => {
cy.wrap(manualNumber).type(innerIdx + 10); // type random number
});
// 버튼이 위에서부터 하나씩 사라지기 때문에 항상 0번째 index를 클릭
cy.get('.manual-input-btn').eq(0).click();
});
}

function typeNotEnoughManualInput() {
// 로또 1장만 입력 후 구매 확정 (오류 테스트)
cy.get('.manual-wrapper')
.eq(0)
.find('.manual-number')
.each((manualNumber, idx) => {
cy.wrap(manualNumber).type(idx + 10); // type random number
});
cy.get('.manual-input-btn').eq(0).click();
}

function typeWinningNumber() {
const numbers = new Set();
while (numbers.size < LOTT0_LENGTH) {
numbers.add(getRandomNumber());
numbers.add(getRandomNumber(1, LOTTO_NUMBERS.LOTTO_MAX_NUM));
}

cy.get('.winning-number').each((winningNumber, idx) => {
cy.wrap(winningNumber).type([...numbers][idx]);
});
}

it('프로그램을 시작하면 구입금액 입력폼만 보인다.', () => {
it('프로그램을 시작하면 구매 방식(자동/수동) 선택지와 구입금액 입력폼이 보인다.', () => {
cy.get('#purchase-type').should('be.visible');
cy.get('#input-price-form').should('be.visible');
cy.get('#purchased-lottos').should('not.be.visible');
cy.get('#winning-numbers-form').should('not.be.visible');
});

it('사용자는 로또 구입 금액을 입력하면, 확인 버튼을 누르면 사용자가 구매한 로또와 지난 주 당첨 로또 입력폼이 보인다.', () => {
it('구매 방식(자동/수동) 선택지를 클릭하면 버튼의 배경색이 서로 바뀐다.', () => {
cy.get('#auto-btn').click();
cy.get('#auto-btn').should('have.class', 'btn-cyan');
cy.get('#manual-btn').click();
cy.get('#manual-btn').should('have.class', 'btn-cyan');
});

it('수동 구매를 선택하고 금액을 입력하면, 금액만큼의 번호 입력 폼을 보여준다.', () => {
cy.get('#manual-btn').click();
clickAfterTypePrice();

cy.get('.manual-wrapper').should('have.length', lottoTotalCount);
});

it('수동 구매 번호를 모두 올바르게 입력하면, 확정된 로또 티켓을 보여준다.', () => {
cy.get('#manual-btn').click();
clickAfterTypePrice();
typeManualNumberAndConfirm();

cy.get('.manual-wrapper').each(manualTicket => {
cy.wrap(manualTicket).find('.lotto-detail').should('be.visible');
});
});

it('수동 구매 후 남는 금액 발생 시 자동 구매 진행 확인창이 뜬다. ', () => {
const alertStub = cy.stub();
cy.on('window:confirm', alertStub);

cy.get('#manual-btn').click();
clickAfterTypePrice();
typeNotEnoughManualInput();

cy.get('#manual-confirm-btn')
.click()
.then(() => {
expect(alertStub.getCall(0)).to.be.calledWith(
'남은 금액은 자동구매로 진행됩니다. 계속하시겠습니까?'
);
});
});

it('수동 구매 후 남는 금액으로 자동 구매 동의 시 자동 구매를 진행한다. ', () => {
const alertStub = cy.stub();
cy.on('window:confirm', alertStub);

cy.get('#manual-btn').click();
clickAfterTypePrice();
typeNotEnoughManualInput();

cy.get('#manual-confirm-btn')
.click()
.then(() => {
expect(alertStub.getCall(0)).to.be.calledWith(
'남은 금액은 자동구매로 진행됩니다. 계속하시겠습니까?'
);
});

cy.on('window:confirm', () => true);
cy.get('#purchased-lottos').should('be.visible');
});

it('자동 구매 시 로또 구입 금액을 입력하고 확인 버튼을 누르면 사용자가 구매한 로또와 지난 주 당첨 로또 입력폼이 보인다.', () => {
clickAfterTypePrice();

cy.get('#purchased-lottos').should('be.visible');
cy.get('#winning-numbers-form').should('be.visible');
});

it('사용자는 로또 구입 금액을 입력하면, Enter를 누르면 사용자가 구매한 로또와 지난 주 당첨 로또 입력폼이 보인다.', () => {
it('자동 구매 시 사용자가 로또 구입 금액 입력 후 enter를 누르면 사용자가 구매한 로또와 지난 주 당첨 로또 입력폼이 보인다.', () => {
cy.get('#input-price').type(`${price}{enter}`);
cy.get('#purchased-lottos').should('be.visible');
cy.get('#winning-numbers-form').should('be.visible');
Expand Down Expand Up @@ -74,7 +161,7 @@ describe('로또 게임 테스트', () => {
cy.get('.lotto-wrapper').children('.lotto-detail').should('not.be.visible');
});

it('모든 숫자의 입력을 완료하면, 결과 확인 버튼이 활성화된다.', () => {
it('당첨 숫자를 모두 입력하면, 결과 확인 버튼이 활성화된다.', () => {
clickAfterTypePrice();
typeWinningNumber();

Expand Down Expand Up @@ -119,8 +206,7 @@ describe('로또 게임 테스트', () => {
const rankCounts = [1, 1, 0, 0, 2];

lottoNumsArr.forEach(lottoNums => {
const lotto = new Lotto();
lotto.inputManualNumbers(new Set(lottoNums));
const lotto = new Lotto(lottoNums);
lottos.push(lotto);
});

Expand All @@ -137,8 +223,7 @@ describe('로또 게임 테스트', () => {
const earningRate = (sum / purchasedPrice - 1) * 100;

lottoNumsArr.forEach(lottoNums => {
const lotto = new Lotto();
lotto.inputManualNumbers(new Set(lottoNums));
const lotto = new Lotto(lottoNums);
lottos.push(lotto);
});

Expand All @@ -149,6 +234,22 @@ describe('로또 게임 테스트', () => {
expect(lottoProcessor.earningRate).to.be.equal(earningRate);
});

it('두개의 숫자를 입력하면, 자동으로 다음 숫자 칸으로 focus가 이동한다.', () => {
clickAfterTypePrice();

for (let i = 0; i < LOTT0_LENGTH; i++) {
cy.get('.winning-number')
.eq(i)
.type(String(10 + i));

if (i === LOTT0_LENGTH - 1) break;

cy.get('.winning-number')
.eq(i + 1)
.should('be.focused');
}
});

it('다시 시작하기 버튼을 누르면 초기화 되서 다시 구매를 시작할 수 있다.', () => {
clickAfterTypePrice();
typeWinningNumber();
Expand All @@ -168,20 +269,4 @@ describe('로또 게임 테스트', () => {
cy.wrap(winningNumber).should('have.value', '');
});
});

it('두개의 숫자를 입력하면, 자동으로 다음 숫자 칸으로 focus가 이동한다.', () => {
clickAfterTypePrice();

for (let i = 0; i < LOTT0_LENGTH; i++) {
cy.get('.winning-number')
.eq(i)
.type(String(10 + i));

if (i === LOTT0_LENGTH - 1) break;

cy.get('.winning-number')
.eq(i + 1)
.should('be.focused');
}
});
});
28 changes: 27 additions & 1 deletion cypress/integration/lottoTest/lottoValidation.spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ describe('로또 금액 입력 예외 처리 테스트', () => {
cy.visit('http://127.0.0.1:5500/');
});

const price = 10000;
const price = 5000;

function exceptionAlert(wrongPrice, alertMessage) {
const alertStub = cy.stub();
Expand All @@ -16,6 +16,17 @@ describe('로또 금액 입력 예외 처리 테스트', () => {
});
}

function manualNumberAlert(alertMessage, idx) {
const alertStub = cy.stub();
cy.on('window:alert', alertStub);
cy.get('.manual-input-btn')
.eq(idx)
.click()
.then(() => {
expect(alertStub.getCall(0)).to.be.calledWith(alertMessage);
});
}

function winningNumberAlert(alertMessage) {
const alertStub = cy.stub();
cy.on('window:alert', alertStub);
Expand Down Expand Up @@ -61,8 +72,23 @@ describe('로또 금액 입력 예외 처리 테스트', () => {
cy.get('#winning-numbers-form').should('not.be.visible');
});

it('수동 구매 시 로또 번호에는 중복된 숫자를 입력할 수 없다.', () => {
cy.get('#manual-btn').click();
clickAfterTypePrice();

cy.get('.manual-wrapper').each((manualTicket, idx) => {
cy.wrap(manualTicket)
.find('.manual-number')
.each(manualNumber => {
cy.wrap(manualNumber).type('7');
});
manualNumberAlert('로또 번호에는 중복된 숫자를 입력할 수 없습니다.', idx);
});
});

it('로또 당첨 번호에는 중복된 숫자를 입력할 수 없다.', () => {
clickAfterTypePrice();

cy.get('.winning-number').each(winningNumber => {
cy.wrap(winningNumber).type('7');
});
Expand Down
Loading