Fakultas Ilmu Komputer UI

Commit 91ecf774 authored by Yasmin Adelia Puti Chaidir's avatar Yasmin Adelia Puti Chaidir
Browse files

Merge branch 'staging' of...

Merge branch 'staging' of https://gitlab.cs.ui.ac.id/ppl-fasilkom-ui/2021/DD/justika-pengembangan-platform-untuk-umkm/justika-umkm-legal-frontend into PBI-1-halaman-utama
parents 375da841 03306d27
Pipeline #75636 passed with stages
in 11 minutes and 26 seconds
...@@ -4,7 +4,8 @@ ...@@ -4,7 +4,8 @@
"eslint:recommended", "eslint:recommended",
"plugin:react/recommended", "plugin:react/recommended",
"plugin:react-hooks/recommended", "plugin:react-hooks/recommended",
"plugin:testing-library/recommended" "plugin:testing-library/recommended",
"plugin:cypress/recommended"
], ],
"env": { "env": {
"browser": true, "browser": true,
......
...@@ -68,6 +68,23 @@ build: ...@@ -68,6 +68,23 @@ build:
paths: paths:
- node_modules/ - node_modules/
integration:
image: cypress/browsers:node12.16.2-chrome81-ff75
stage: test-build
script:
- apt-get install xvfb
- npm run cypress:install
- npm run start:gitlab
- npm run cypress:gitlab
except:
changes:
- "README.md"
cache:
key: dependency
policy: pull
paths:
- node_modules/
SonarScanner Dev: SonarScanner Dev:
image: image:
name: sonarsource/sonar-scanner-cli:4.6 name: sonarsource/sonar-scanner-cli:4.6
......
{
"baseUrl": "http://localhost:3000",
"video": false,
"defaultCommandTimeout": 6000
}
import '../support/commands'
describe('Submit to Backend PT (Success Case)', () => {
beforeEach(() => {
cy.login()
cy.visit('/form-pt')
cy.get('[data-testid="form-1-nama-field"]').type('PT Justika')
cy.get('[data-testid="form-1-status-pt"]').click()
cy.get('[data-testid="form-1-alamat-field"]').type('Jalan Terbang Layang')
cy.get('[data-testid="form-1-barang-jasa-field"]').type('Layanan hukum')
cy.get('[data-testid="lanjut-button"]').click()
cy.get('[data-testid="form-iumk-2-jumlah-karyawan"]').click()
cy.get('[data-testid="data-employee-1"]').click()
cy.get('[data-testid="form-iumk-2-kbli"]').type('12345')
cy.get('[data-testid="form-iumk-2-catatan"]').type(
'Saya sudah memiliki dokumen A, B',
)
cy.get('[data-testid="lanjut-button"]').click()
cy.intercept(
{
method: 'POST',
url: '**/api/v1/pt/',
},
{
statusCode: 200,
},
).as('postCreatePTSukses')
cy.get('[data-testid="submit-button"]').click()
})
it('should have correct body response', () => {
cy.wait('@postCreatePTSukses').should(({request}) => {
expect(request.body).to.have.property('nama_usaha')
expect(request.body).to.have.property('alamat')
expect(request.body).to.have.property('barang_jasa')
expect(request.body).to.have.property('status_entitas')
expect(request.body).to.have.property('jumlah_karyawan')
expect(request.body).to.have.property('kode_kbli')
expect(request.body).to.have.property('catatan')
})
})
it('should directed to / and show success toast after success register', () => {
cy.wait('@postCreatePTSukses')
cy.url().should('include', '/')
cy.get('[data-testid=toast-homepage]').should('be.visible')
})
})
describe('Submit to Backend PT (Error Case)', () => {
beforeEach(() => {
cy.login()
cy.visit('/form-pt')
cy.get('[data-testid="form-1-nama-field"]').type('PT Justika')
cy.get('[data-testid="form-1-status-pt"]').click()
cy.get('[data-testid="form-1-alamat-field"]').type('Jalan Terbang Layang')
cy.get('[data-testid="form-1-barang-jasa-field"]').type('Layanan hukum')
cy.get('[data-testid="lanjut-button"]').click()
cy.get('[data-testid="form-iumk-2-jumlah-karyawan"]').click()
cy.get('[data-testid="data-employee-1"]').click()
cy.get('[data-testid="form-iumk-2-kbli"]').type('12345')
cy.get('[data-testid="form-iumk-2-catatan"]').type(
'Saya sudah memiliki dokumen A, B',
)
cy.get('[data-testid="lanjut-button"]').click()
cy.intercept(
{
method: 'POST',
url: '**/api/v1/pt/',
},
{
statusCode: 400,
body: {non_field_errors: 'Kode KBLI hanya boleh angka'},
},
).as('postCreatePTError')
cy.get('[data-testid="submit-button"]').click()
})
it('show error toast after error register', () => {
cy.wait('@postCreatePTError')
cy.url().should('include', '/')
cy.get('[data-testid=toast-error]').should('be.visible')
})
})
import '../support/commands'
describe('Submit to Backend IUMK (Success Case)', () => {
beforeEach(() => {
cy.login()
cy.visit('/form-iumk')
cy.get('[data-testid="form-1-nama-field"]').type('PT Justika')
cy.get('[data-testid="form-1-status-pt"]').click()
cy.get('[data-testid="form-1-alamat-field"]').type('Jalan Terbang Layang')
cy.get('[data-testid="form-1-barang-jasa-field"]').type('Layanan hukum')
cy.get('[data-testid="lanjut-button"]').click()
cy.get('[data-testid="form-iumk-2-jumlah-karyawan"]').click()
cy.get('[data-testid="data-employee-1"]').click()
cy.get('[data-testid="form-iumk-2-kbli"]').type('12345')
cy.get('[data-testid="form-iumk-2-catatan"]').type(
'Saya sudah memiliki dokumen A, B',
)
cy.get('[data-testid="lanjut-button"]').click()
cy.intercept(
{
method: 'POST',
url: '**/api/v1/iumk/',
},
{
statusCode: 200,
},
).as('postCreateIumkSukses')
cy.get('[data-testid="submit-button"]').click()
})
it('should have correct body response', () => {
cy.wait('@postCreateIumkSukses').should(({request}) => {
expect(request.body).to.have.property('nama_usaha')
expect(request.body).to.have.property('alamat')
expect(request.body).to.have.property('barang_jasa')
expect(request.body).to.have.property('status_entitas')
expect(request.body).to.have.property('jumlah_karyawan')
expect(request.body).to.have.property('kode_kbli')
expect(request.body).to.have.property('catatan')
})
})
it('should directed to / and show success toast after success register', () => {
cy.wait('@postCreateIumkSukses')
cy.url().should('include', '/')
cy.get('[data-testid=toast-homepage]').should('be.visible')
})
})
describe('Submit to Backend IUMK (Error Case)', () => {
beforeEach(() => {
cy.login()
cy.visit('/form-iumk')
cy.get('[data-testid="form-1-nama-field"]').type('PT Justika')
cy.get('[data-testid="form-1-status-pt"]').click()
cy.get('[data-testid="form-1-alamat-field"]').type('Jalan Terbang Layang')
cy.get('[data-testid="form-1-barang-jasa-field"]').type('Layanan hukum')
cy.get('[data-testid="lanjut-button"]').click()
cy.get('[data-testid="form-iumk-2-jumlah-karyawan"]').click()
cy.get('[data-testid="data-employee-1"]').click()
cy.get('[data-testid="form-iumk-2-kbli"]').type('12345')
cy.get('[data-testid="form-iumk-2-catatan"]').type(
'Saya sudah memiliki dokumen A, B',
)
cy.get('[data-testid="lanjut-button"]').click()
cy.intercept(
{
method: 'POST',
url: '**/api/v1/iumk/',
},
{
statusCode: 400,
body: {non_field_errors: 'Kode KBLI hanya boleh angka'},
},
).as('postCreateIumkError')
cy.get('[data-testid="submit-button"]').click()
})
it('show error toast after error register', () => {
cy.wait('@postCreateIumkError')
cy.url().should('include', '/')
cy.get('[data-testid=toast-error]').should('be.visible')
})
})
describe('Submit to Backend Validate Email (Success Case)', () => {
beforeEach(() => {
cy.intercept(
{
method: 'POST',
url: '**/api/v1/auth/validate-email/',
},
{
statusCode: 200,
},
).as('postValidateEmailSuccess')
cy.visit('/login')
cy.contains('Email').type('a@gmail.com')
cy.get('[data-testid=next-button]').click()
})
it('should have correct body response', () => {
cy.wait('@postValidateEmailSuccess').should(({request}) => {
expect(request.body).to.have.property('email')
})
})
it('should directed to next page if email is validated', () => {
cy.wait('@postValidateEmailSuccess')
cy.url().should('include', '/login')
cy.get('[data-testid=password-input]').should('be.visible')
})
})
describe('Submit to Backend Validate Email (Error Case)', () => {
beforeEach(() => {
cy.intercept(
{
method: 'POST',
url: '**/api/v1/auth/validate-email/',
},
{
statusCode: 400,
body: {non_field_errors: 'Email is not registered yet.'},
},
).as('postValidateEmailError')
cy.visit('/login')
cy.contains('Email').type('a@gmail.com')
cy.get('[data-testid=next-button]').click()
})
it('should show toast error if email is not registered', () => {
cy.wait('@postValidateEmailError')
cy.get('[data-testid=toast-error-login]').should('be.visible')
})
})
describe('Submit to Backend Login (Success Case)', () => {
beforeEach(() => {
cy.intercept(
{
method: 'POST',
url: '**/api/v1/auth/validate-email/',
},
{
statusCode: 200,
},
).as('postValidateEmailSuccess')
cy.visit('/login')
cy.contains('Email').type('a@gmail.com')
cy.get('[data-testid=next-button]').click()
cy.contains('Password').type('abcdefgh1')
cy.intercept(
{
method: 'POST',
url: '**/api/v1/auth/login/',
},
{
statusCode: 200,
},
).as('postLoginSuccess')
cy.contains('Masuk').click()
})
it('should have correct body response', () => {
cy.wait('@postLoginSuccess').should(({request}) => {
expect(request.body).to.have.property('email')
expect(request.body).to.have.property('password')
})
})
it('should directed to / and show success toast after success login', () => {
cy.wait('@postLoginSuccess')
cy.url().should('include', '/')
cy.get('[data-testid=toast-homepage]').should('be.visible')
})
})
describe('Submit to Backend Login (Error Case)', () => {
beforeEach(() => {
cy.visit('/login')
cy.intercept(
{
method: 'POST',
url: '**/api/v1/auth/validate-email/',
},
{
statusCode: 200,
},
).as('postValidateEmailSuccess')
cy.contains('Email').type('a@gmail.com')
cy.get('[data-testid=next-button]').click()
cy.contains('Password').type('abcdefgh1')
cy.intercept(
{
method: 'POST',
url: '**/api/v1/auth/login/',
},
{
statusCode: 404,
body: {non_field_errors: 'Password is wrong'},
headers: {'access-control-allow-origin': '*'},
delayMs: 500,
},
).as('postLoginError')
cy.contains('Masuk').click()
})
it('shows non field error toast after post error in Login', () => {
cy.wait('@postLoginError')
cy.contains('Password is wrong').scrollIntoView().should('be.visible')
})
})
describe('Submit to Backend Register (Success Case)', () => {
beforeEach(() => {
cy.visit('/register')
cy.contains('Email').type('a@gmail.com')
cy.contains('No Handphone Aktif').type('812345678')
cy.contains('Password').type('abcdefgh1')
cy.contains('Konfirmasi Password').type('abcdefgh1')
cy.intercept(
{
method: 'POST',
url: '**/api/v1/auth/register/',
},
{
statusCode: 200,
},
).as('postRegisterSuccess')
cy.get('[data-testid=daftar]').click()
})
it('should have correct body response', () => {
cy.wait('@postRegisterSuccess').should(({request}) => {
expect(request.body).to.have.property('email')
expect(request.body).to.have.property('phone_number')
expect(request.body).to.have.property('password')
})
})
it('should directed to / and show success toast after success register', () => {
cy.wait('@postRegisterSuccess')
cy.url().should('include', '/')
cy.get('[data-testid=toast-homepage]').should('be.visible')
})
})
describe('Submit to Backend Register (Error Case)', () => {
beforeEach(() => {
cy.visit('/register')
cy.contains('Email').type('a@gmail.com')
cy.contains('No Handphone Aktif').type('812345678')
cy.contains('Password').type('abcdefgh1')
cy.contains('Konfirmasi Password').type('abcdefgh1')
})
it('shows email error toast after post error in email', () => {
cy.intercept(
{
method: 'POST',
url: '**/api/v1/auth/register/',
},
{
statusCode: 404,
body: {email: 'Email already exists'},
headers: {'access-control-allow-origin': '*'},
delayMs: 500,
},
).as('postRegisterEmailError')
cy.get('[data-testid=daftar]').click()
cy.wait('@postRegisterEmailError')
cy.contains('Email already exists').scrollIntoView().should('be.visible')
})
it('shows non field error toast after post error in non field', () => {
cy.intercept(
{
method: 'POST',
url: '**/api/v1/auth/register/',
},
{
statusCode: 404,
body: {non_field_errors: 'Password is too common'},
headers: {'access-control-allow-origin': '*'},
delayMs: 500,
},
).as('postRegisterNonFieldError')
cy.get('[data-testid=daftar]').click()
cy.wait('@postRegisterNonFieldError')
cy.contains('Password is too common').scrollIntoView().should('be.visible')
})
})
module.exports = (on, config) => {
// `on` is used to hook into various events Cypress emits
// `config` is the resolved Cypress config
// https://github.com/cypress-io/cypress/issues/349
// add --disable-dev-shm-usage chrome flag
on('before:browser:launch', (browser, launchOptions) => {
if (browser.family === 'chromium') {
console.log('Adding Chrome flag: --disable-dev-shm-usage')
launchOptions.args.push('--disable-dev-shm-usage')
}
return launchOptions
})
return config
}
function adaptToReduxPersist(mockValue) {
// redux-persist converts total value and top-level properties to //string:
// Es: {a: {foo: 'bar'}} -> {a: JSON.stringify({foo: 'bar'})} -> //JSON.stringify({a: JSON.stringify({foo: 'bar'})});
// so in order for the tests to work properly, we need to simulate //this behavior
const partialConversion = Object.keys(mockValue).reduce((acc, key) => {
acc[key] = JSON.stringify(mockValue[key])
return acc
}, {})
return JSON.stringify(partialConversion)
}
Cypress.Commands.add('login', () => {
window.localStorage.setItem(
'persist:root',
adaptToReduxPersist({
auth: {
token: 'contoh',
email: 'a@gmail.com',
phone_number: '08123456789',
},
}),
)
})
This diff is collapsed.
...@@ -7,7 +7,6 @@ ...@@ -7,7 +7,6 @@
"@reduxjs/toolkit": "^1.5.1", "@reduxjs/toolkit": "^1.5.1",
"@testing-library/jest-dom": "^5.11.9", "@testing-library/jest-dom": "^5.11.9",
"@testing-library/react": "^11.2.5", "@testing-library/react": "^11.2.5",
"@testing-library/user-event": "^12.8.1",
"autoprefixer": "^10.2.5", "autoprefixer": "^10.2.5",
"axios": "^0.21.1", "axios": "^0.21.1",
"msw": "^0.28.0", "msw": "^0.28.0",
...@@ -18,10 +17,13 @@ ...@@ -18,10 +17,13 @@
"react-hot-toast": "^1.0.2", "react-hot-toast": "^1.0.2",
"react-redux": "^7.2.3", "react-redux": "^7.2.3",
"react-scripts": "4.0.3", "react-scripts": "4.0.3",
"react-toast": "^1.0.1",
"redux": "^4.0.5", "redux": "^4.0.5",
"redux-persist": "^6.0.0", "redux-persist": "^6.0.0",
"redux-thunk": "^2.3.0", "redux-thunk": "^2.3.0",
"router": "^1.3.5",
"tailwindcss": "^2.0.3", "tailwindcss": "^2.0.3",
"wait-on": "^5.3.0",
"web-vitals": "^1.1.0" "web-vitals": "^1.1.0"
}, },
"scripts": { "scripts": {
...@@ -35,7 +37,12 @@ ...@@ -35,7 +37,12 @@
"test:coverage": "CI=true npm run test --env=jsdom -- --coverage", "test:coverage": "CI=true npm run test --env=jsdom -- --coverage",
"lint": "eslint .", "lint": "eslint .",
"lint:fix": "eslint --fix .", "lint:fix": "eslint --fix .",
"format": "prettier --write \"**/*.+(js|jsx|json|css)\"" "format": "prettier --write \"**/*.+(js|jsx|json|css)\"",
"cypress:open": "cypress open",
"cypress:run": "cypress run",
"cypress:install": "cypress install",
"cypress:gitlab": "CYPRESS_BASE_URL=http://172.17.0.3:3000/ xvfb-run cypress run --headed --browser chrome",
"start:gitlab": "npm start & wait-on http://172.17.0.3:3000/"
}, },
"eslintConfig": { "eslintConfig": {
"extends": [ "extends": [
...@@ -57,17 +64,23 @@ ...@@ -57,17 +64,23 @@
}, },
"jest": { "jest": {
"coveragePathIgnorePatterns": [ "coveragePathIgnorePatterns": [
"index.js" "index.js",
"src/api/*"
] ]
}, },
"devDependencies": { "devDependencies": {
"@testing-library/user-event": "^12.8.3",
"cypress": "^6.8.0",
"eslint": "^7.22.0", "eslint": "^7.22.0",
"eslint-plugin-cypress": "^2.11.2",
"eslint-plugin-jest": "^24.3.2", "eslint-plugin-jest": "^24.3.2",
"eslint-plugin-react": "^7.22.0", "eslint-plugin-react": "^7.22.0",
"eslint-plugin-react-hooks": "^4.2.0", "eslint-plugin-react-hooks": "^4.2.0",
"eslint-plugin-testing-library": "^3.10.1", "eslint-plugin-testing-library": "^3.10.1",
"husky": "^5.1.3", "husky": "^5.1.3",
"jest-environment-jsdom-sixteen": "^1.0.3",
"lint-staged": "^10.5.4", "lint-staged": "^10.5.4",