BAB III METODOLOGI PENELITIAN
3.4 Pengujian Black Box
Pengujian Black Box pada penelitian ini akan berfokus pada pengujian tombol- tombol dan fitur yang tersedia pada setiap halaman. Hali ini dilakukan untuk mengetahui apakah respon dari sistem sesuai yang dengan requirement dan skenario yang seharusnya.
Semua informasi dan respon pada yang muncul pada halaman yang akan diuji menjadi nilai untuk mengetahui apakah masih ada kesalahan dalam pembuatan atau masih perlu
tambahan dan koreksi pada setiap menunya. Tabel 3.1 merupakan rincian skenario pengujian Black Box.
Tabel 3.1 Pengujian Black Box
No Halaman Tindakan Hasil yang diharapkan
1 Halaman home
Menekan tombol Get Started. Sistem menampilkan halaman signup.
Menehan tombol Home. Sistem menampilkan halaman home.
Menekan tombol Signup. Sistem menampilkan halaman signup.
Menekan tombol Login. Sistemn menampilkan halaman login.
2 Halaman signup
Mengisi form signup dengan mengosongkan bagian Full Name saja lalu menekan tombol Register.
Sistem akan menampilkan pemberitahuan “Please enter your full name”.
Mengisi form signup dengan mengosongkan bagian Email saja lalu menekan tombol Register.
Sistem akan menampilkan pemberitahuan “Please enter your email” .
Mengisi form signup dengan email yang telah terdaftar lalu menekan tombol Register.
Sistem akan menampilkan pemberitahuan “This email already registered” .
Mengisi form sigunp dengan mengosongkan bagian Password lalu menekan tombol Register.
Sistem akan menampilkan pemberitahuan “Please enter your password” .
Mengisi form signup dengan mengisi Password kurang dari 6 karakter lalu menekan tombol Register.
Sistem akan menampilkan pemberitahuan “Password must be at least 6 characters” .
Mengisi form signup dengan mengisi password berbeda pada bagian Password dan Password Confirm lau menekan tombol Register.
Sistem akan menampilkan pemberitahuan “Password don't match” .
Mengisi form signup dan memasukkan password yang sama dengan jumlah 6 karakter pada bagian Password dan Password Confirm.
Sistem akan menampilkan halaman login.
3 Halaman login
Memasukkan email dan password yang benar.
Sistem akan menampilkan halaman dashboard.
Memasukkan email dan/atau password yang salah.
Sistem akan menampilkan pemberitahuan “Incorrect email or password”.
4 Halaman dashboard
Menekan tombol Dashboard. Sistem akan menampilkan halaman dashboard.
Menekan tombol Logout. Sistem akan menampilkan halaman home.
Menekan tombol Create Event. Sistem akan menampilkan halaman create event.
Menekan tombol Details pada bagian event created.
Sistem akan menampilkan halaman event
Menekan tombol Delete pada bagian event created.
Sistem akan menghapus event yang di-delete.
Menekan tombol Details pada bagian event partisipated.
Sistem akan menampilkan halaman sertifikat.
5 Halaman create event
Mengisi semua form selain bagian Event Image lalu menekan tombol Save Event.
Sistem akan menampilkan pemberitahuan “File is not an image”.
Mengisi seluruh form lalu menekan tombol Save Event.
Sistem akan menampilkan halaman dashboard dan event yang telah dibuat muncul pada bagian Event Created.
6 Halaman event
Memasukkan file .csv sesuai instruksi pada halaman event lalu menekan tombol Upload.
Sistem akan memuat ulang halaman event lalu akan tampil tabel peserta sesuai isi file csv.
Menekan tombol Layout Design. Sistem akan menampilkan halaman layout
7 Halaman layout
Menekan tombol template, lalu memilih salah satu gambar template yang disediakan.
Background sertifikat akan berubah sesuai gambar template yang di pilih.
Mengisi bagian Add Sign Attribute untuk menambahkan nama yang bertanda tangan dan jabatannya, lalu menekan tombol Add.
Akan tampil nama yang bertanda tangan pada side menu.
Menekan tombol silang pada list yang bertanda tangan pada side menu.
List tersebut akan terhapus dari database.
Menekan tombol Save Layout. Sistem akan menampilkan halaman dashboard dan user dapat men-download file sertifikat melalui halaman event atau halaman sertifikat.
8 Halaman sertifikat
Menekan tombol download. Sistem akan men-download file Pdf.
9 Scaning QR Code
Melakukan scanning pada QR Code mengunakan smartphone
Hasil scan akan menampilkan sebual URL menuju halaman sertifikat
BAB IV PEMBAHASAN
4.1 Analisis Alur Kerja Program 4.1.1 Halaman Utama (Home)
Gambar 4.1 Halaman utama (Home Page).
Halaman ini berisi pengenalan website secara singkat dan fitur-fitur yang disediakan. Tidak banyak hal yang bisa dilakukan user di halaman ini. User akan diarahkan untuk mendaftar terlebih dahulu jika belum terdaftar dengan menekan tombol Get Started atau tombol Signup di bagian navbar. User yang telah mendaftar akan dapat
Di halaman ini tidak banyak logika yang dijalankan. Ketika user mengunjungi website sistem akan menerima request berupa HTTP GET, kemudian mengirimkan response berupa tampilan halaman home.
4.1.2 Halaman Signup
Gambar 4.2 Halaman signup
Pada halaman signup ini, user harus mengisi semua kolom yang disediakan. Mulai dari nama lengkap, email, password dan konfirmasi password. Kolom nama lengkap harus diisi dengan nama lengkap user agar nama yang dicetak di sertifikat benar-benar nama lengkap user. Jika kolom nama lengkap tidak diisi maka akan tampil pemberitahuan
“Please enter your full name”. Kolom email juga harus diisi dengan email aktif milik user agar dapat menerima pemberitahuan dari sistem. Jika user tidak memasukkan email maka akan tampil pemberitahuan “Please enter your email”. Email bersifat unik, sehingga user tidak dapat menggunakan email yang telah terdaftar, jika user mengunakan email yang telah terdaftar makan akan muncul pemberitahuan “This email already registered”.
Kolom password harus diisi dengan karakter dengan panjang minimal 6 karakter, jika password yang dimasukkan kurang dari 6 karakter maka akan tampil pemberitahuan
“Password must be at least 6 characters”.
Konfirmasi password pada halaman ini bertujuan agar user lebih yakin bahwa password yang dimasukkan benar. Ketika user memasukkan password-nya pada kedua kolom, sistem akan membandingkan kedua password, jika tidak sama maka akan muncul pemberitahuan “Password don’t match”. Untuk keamanan password, sistem ini menggunakan library javascript BCrypt untuk melakukan hashing password.
4.1.3 Halaman Login
Gambar 4.3 Halaman login
Setelah mendaftar user dapat langsung melakukan login untuk selanjutnya diarahkan menuju ke halaman dashboard. User yang dapat melakukan login adalah user yang terdaftar. Baik itu terdaftar karena mendaftar sendiri maupun didaftarkan oleh organizer event karena mengikuti sebuah event. Peserta sebuah event akan secara otomatis terdaftar di sistem mengunakan email dari dokumen data peserta yang dimiliki organizer event. Jika user memasukkan email dan password yang salah maka akan tampil pemberitahuan “Invalid email or password”.
4.1.4 Halaman Dashboard
Halaman pada Gambar 4.4 merupakan halaman dashboard yang akan tampil ketika user berhasil login. Pada halaman ini user dapat mengelola event yang telah dibuat dan event yang telah diikuti. User dapat membuat event dengan menekan tombol ”Create Event” kemudian akan diarahkan menuju halaman create event. Halaman create event dapat dilihat pada Gambar 4.5. Event yang telah dibuat akan tampil pada bagian “Event Created”. Tombol “Details“ pada bagian “Event Created” akan mengarahkan user menuju halaman event yang berisi detail event yang dibuat. User dapat menghapus event dengan menekan tombol “Delete”. User yang belum pernah mengikuti event yang terdaftar di sistem, makan bagian “Event Partisipated” akan kosong. Jika user menekan tombol “Details” pada bagian “Event Partisipated” maka akan diarahkan langsung ke halaman sertifikat.
Gambar 4.4 Halaman dashboard.
4.1.5 Halaman Create Event
Untuk membuat event, user harus mengisi detail event sesuai form yang ada pada Gambar 4.5. Pada halaman ini pengguna belum dapat melampirkan data peserta event.
data peserta event dapat di lampirkan setelah event dibuat.
Gambar 4.5 Halaman create event.
4.1.6 Halaman Event
Gambar 4.6 merupakan tampilan halaman event setelah event dibuat. Halaman ini hanya berisi detail event berdasarkan form yang diisi di halaman Create Event. Pada Gambar 4.6 pengguna akan diminta untuk memasukkan data dalam bentuk file CSV (Comma Separated Values) agar dapat men-generate sertifikat. File CSV ini berisi data peserta yang mengikuti event. Selanjutnya data peserta akan disimpan oleh sistem satu- persatu untuk keperluan sertifikat. Setelah file CSV tersebut di-upload, halaman event akan seperti Gambar 4.7, akan tampil sebuah tabel berisi nama peserta dan data lainnya.
Gambar 4.6 Halaman event 1.
4.1.7 Halaman Layout
Gambar 4.8 Halaman layout.
Setelah data event dan data peserta tersimpan selanjutnya organizer akan menentukan layout seperti apa yang dinginkan pada halaman layout. Untuk layouting organizer hanya dapat mengubah background dari sertifikat dengan template yang telah disediakan pada sistem. Untuk mengubah background organizer perlu memilih tamplate yang akan digunakan pada menu template. Selanjutnya organizer dapat men-generate sertifikat dengan menekan tombol Save Layout. Setelah selesai organizer akan diarahkan ke halaman event.
4.1.8 Halaman Sertifikat
Halaman ini berisi detail event seperti pada halaman event, perbedaannya di halaman ini akan tampil bentuk sertifikat yang dimiliki user. Halaman ini dapat dikunjungi oleh user terdaftar maupun user umu. Jika user halaman ini dikunjungi oleh user yang telah melakukan login maka akan tampil tombol Download Certificate. User umum dapat mengakses halaman ini dengan melakukan scanning QR Code pada sertifikat, tetapi user umum tidak dapat men-download sertifikat. Halaman sertifikat dapat dilihat pada gambar Gambar 4.9.
Gambar 4.9 Halaman sertifikat.
4.2 Analisis Sistem
4.2.1 Implementasi MongoDB dan Node.js
MongoDB merupakan sebuah konsep database yang berorientasi dokumen dan diklasifikasikan ke dalam NoSQL, berbeda dengan konsep SQL yang berorientasi tabel.
MongoDB menyimpan data dalam bentuk BSON (Binary JSON), yang sangat mirip dengan JSON. BSON merupakan bentuk representasi dari JSON yang disandikan ke dalam bentuk biner (binary-encoded). Dengan penggunaan JSON ini dapat mengefisienkan interaksi MongoDB dalam bahasa pemrograman lainnya (MongoDB, 2020).
Untuk menyimpan data pada MongoDB schema dokumen tidak harus dibuat terlebih dahulu. Hal ini memungkinkan dokumen dalam sebuah collection tidak harus memiliki field dan tipe data yang sama (MongoDB, 2019). Untuk melakukan query MongoDB menyediakan dukungan driver untuk beberapa bahasa pemrograman yaitu Python, Java, Ruby, Node.js, C++, C# dan lain-lain. Tabel menjelaskan perbandingan antara database SQL dengan MongoDB.
Tabel 4.1 Tabel perbandingan SQL dan MongoDB.
Database SQL MongoDB
Tabel Collection
Baris Dokumen (dokumen BSON)
Kolom Field
Indeks Indeks
Entitas Objek
SQL Node.js, Phython, Java, C++, C#, Ruby dll.
Sesuai dengan Tabel 4.1 MongoDB menyediakan driver agar dapat digunakan pada Node.js yang disebut dengan MongoDB Native Driver. Driver tersebut dapat diperoleh melalu NPM dengan perintah npm install –-save mongodb. Pada sistem ini penulis menggunakan Mongoose, sebuah library untuk melakukan mapping objek pada dokumen (Object-Document Mapping). Mongoose menyediakan fungsi-fungsi untuk dapat mengakses data pada MongoDB dengan cara yang lebih mudah dipahami.
Mongoose dibangun di atas MongoDB native driver, tetapi Mongoose dan MongoDB native driver memiliki cara yang berbeda dalam interaksinya dengan MongoDB database.
4.2.1.1 MongoDB Atlas dan MongoDB Compass
MongoDB Atlas adalah sebuah layanan cloud database global yang dikembangkan oleh tim MongoDB. Dapat dikatakan bahwa MongoDB Atlas adalah layanan hosting database MongoDB. MongoDB Compass adalah sebuah GUI untuk MongoDB yang dapat digunakan untuk lokal (localhost) maupun cloud. Keduanya mirip dengan phpMyAdmin yang digunakan untuk menangani administrasi mySQL pada web.
membutuhkan MongoDB connection string yang dapat diperoleh dengan mendaftar di website MongoDB. Berikut adalah bentuk MongoDB connection string:
mongodb+srv://riyanrizky:<password>@auth-system fkckz.mongodb.net/test?retryWrites=true&w=majority
Yang perlu dilakukan hanya mengganti <password> dengan password user yang didaftarkan. Connection string tersebut juga dapat digunakan pada MongoDB Compass agar dapat mengelola cloud melalui desktop. Namun secara default MongoDB disiapkan untuk keperluan database pada localhost. Berikut adalah kode yang digunakan untuk koneksi dengan database MongoDB menggunakan library Mongoose:
const db = config.get('db');
mongoose.connect(db, { useNewUrlParser:true, useUnifiedTopology:
true, useCreateIndex: true, useFindAndModify: false}) .then(() => console.log(`Connected to ${db}`))
.catch(err => { console.error('Could not connect to database', err)});
MongoDB connection string diletakkan pada const db = config.get('db');.
4.2.1.2 Menggunakan Mongoose
Ada beberapa tahap dalam menggunakan Mongoose sebagai ODM. Mongoose menyediakan sebuah constructor Schema() untuk mendeklarasikan bentuk schema dari collection yang akan dibuat. Kode berikut menjelaskan proses deklarasi schema dengan Mongoose untuk menyimpan data template sertifikat:
const templatesSchema = new mongoose.Schema({
templatesName: { type: String, required: true },
path: {
type: String, required: true }
})
const Template = mongoose.model('Template', templatesSchema);
Untuk dapat menggunakan schema templatesSchema Mongoose menyediakan fungsi
model(), ini adalah bagian utama dari Mongoose. Fungsi ini bertindak sebagai pembungkus bentuk schema yang berisi struktur dokumen template sertifikat. Fungsi
model() ini akan menyediakan sebuah interface untuk berinteraksi dengan database dalam menyimpan, memperbarui, menghapus data dan lain-lain.
4.2.1.3 Struktur Dokumen pada MongoDB
Meskipun MongoDB bukan relational database bukan berarti dokumen MongoDB tidak dapat direlasikan. Ada dua metode yang dapat digunakan untuk merelasikan dokumen pada database MongoDB.
1. Embedded Data
Metode ini juga disebut sebagai denormalisasi. Dokumen MongoDB mendukung penyimpanan data dengan menyematkan struktur dokumen pada array atau field dalam sebuah dokumen (MongoDB, 2019). Metode ini sangat cocok digunakan jika data yang disematkan dalam jumlah sedikit dan sering diakses seperti pada relasi one to one dan one to many (misalnya data pemeran sebuah film). Metode embedded ini tidak cocok digunakan untuk menyematkan data yang sangat banyak karena akan membuat ukuran file dokumen menjadi besar. Gambar 4.10 adalah contoh penggunaan metode embedded pada collection event. Objek sign akan berisi array dari signName dan signAs, dimana keduanya adalah kombinasi nama yang bertanda tangan pada sertifikat dan jabatannya.
Gambar 4.10 Penggunaan metode embedded data.
2. References
Metode ini disebut dengan normalisasi. Metode ini menyimpan relasi antar data dengan menyertakan referensi dari satu dokumen ke dokumen lainnya berupa sebuah objek _id (MongoDB, 2019). Ketika data yang direferensi berubah maka akan berubah pula data pada dokumen yang mereferensinya. Konsep ini dalam SQL
menerapkan sebuah algoritma untuk memanfaatkan fungsi yang ada. Gambar 4.11 adalah contoh penggunaan metode reference pada collection event.
Gambar 4.11 Penggunaan metode reference.
Untuk bisa mengakses field lain (selain _id) pada dokumen yang di reference Mongoose menyediakan fungsi pupulate() untuk mengakses semua field dari dokumen yang berelasi. Pada SQL hal ini mirip dengan join. Berikut kode untuk melakukan populate:
const certificate = await Event.find({ userId }).populate ('ownerId');
Penulis menerapkan metode reference ini pada semua collection.
4.2.2 Proses Signup
Proses signup terdiri dari beberapa proses yang ditunjukan pada Gambar 4.12.
Email user tidak boleh sama sehingga sebelum data disimpan sistem akan mengecek data email yang telah digunakan. Sebelum data disimpan dalam database, password terlebih dahulu dikodekan agar data password aman dari pencurian. Berikut kode yang digunakan untuk proses signup:
const name = req.body.name;
const email = req.body.email;
const password = req.body.password;
const passwordRepeat = req.body.passwordRepeat;
let user = await User.findOne({ email: email });
if (user) {
req.flash('error', 'This email already registered');
return res.redirect('/signup');
}
const { error } = validateRegister({ name, email, password, pass wordRepeat });
if (error) {
req.flash('error', error.message) return res.redirect('/signup');
}
user = new User({ name, email, password });
const salt = await bcrypt.genSalt(10);
user.password = await bcrypt.hash(user.password, salt);
await user.save();
return res.redirect('/login');
Pada database SQL data disimpan dalam bentuk tabel, sehingga untuk menyimpan data tabelnya harus dibuat terlebih dahulu. Begitu pula pada MongoDB, bentuk dokumen data perlu di jelaskan agar dapat menyimpannya. Berikut adalah kode untuk menjelaskan bentuk dokumen dari data user:
const userSchema = new mongoose.Schema({
name: {
type: String, required: true, minlength: 2, maxlength: 50 },
email: {
type: String, required: true, unique: true, minlength: 5, maxlength: 255, unique: true },
required: true, minlength: 6, maxlength: 255 }
});
const User = mongoose.model('User', userSchema);
Karena MongoDB menggunakan javascript dalam penggunaannya, maka hal ini dapat memudahkan interaksi antara MongoDB dan Node.js di sisi server. Penulis menggunakan library Mongoose untuk menyederhanakan penulisan kode sehingga penulisan kode untuk interaksi sistem dengan database lebih sederhana. Data user kemudian disimpan dengan memafaatkan objek pada kode User di atas. Setelah disimpan sebuah dokumen akan berbentuk seperti Gambar 4.13.
Gambar 4.13 Bentuk dokumen user.
Berbeda dengan SQL, MongoDB secara otomatis akan membuat “_id” untuk setiap dokumen berupa string unik dengan panjang 24 karakter. Proses hashing pada password akan menghasilkan string dengan Panjang 60 karakter untuk setiap password yang disimpan, hal ini tegantung dari bit salt yang digunakan, sedangkan penulis menggunakan 10 bit.
4.2.3 Proses Login
Bcrypt menyediakan fungsi compare()untuk membandingkan password yang berasal dari form input dengan data yang ada di database.
Gambar 4.15 Bentuk dokumen session.
Jika email dan password yang dimasukkan benar maka sistem akan menyimpan sebuah session ke dalam database. Untuk session penulis menggunakan library express- session dan connect-mongodb-session, dengan library ini sistem dapat menyimpan dokumen session tanpa membuat schema dokumennya. Bentuk dokumen session dapat dilihat pada Gambar 4.15. Session akan berakhir jika user melakukan logout atau menutup browsher-nya. Berikut adalah kode yang digunakan untuk proses login:
const { error } = validateLogin(req.body);
if (error) {
req.flash('error', error.message);
return res.redirect('/login');
}
let user = await User.findOne({ email: req.body.email });
if (!user) {
req.flash('error', 'Invalid email or password');
return res.redirect('/login');
}
const validPassword = await bcrypt.compare(req.body.password, user.password);
if (!validPassword) {
req.flash('error', 'Invalid email or password');
return res.redirect('/login');
}
req.session.isLoggedIn = true;
req.session.user = user;
return req.session.save(() => { res.redirect('/dashboard');
});
4.2.4 Proses Add Partisipants
Untuk memasukkan data peserta ke sistem organizer dapat mengupload data dalam format file CSV. File ini kemudian akan dibaca sistem satu-persatu melalui browsher, proses ini disebut dengan parsing. Untuk melakukan parsing data pada file CSV yang diupload, penulis menggunakan Papaparse. Papaparse dapat mendeteksi secara otomatis karakter delimiter (pembatas) pada file CSV, serta menyediakan method step untuk membaca file CSV per baris. Berikut adalah kode untuk proses parsing data peserta:
const eventId = req.body.eventId;
const csvPath = req.file.path;
const file = fs.createReadStream(csvPath);
Papa.parse(file, { header: true,
skipEmptyLines: true,
step: async function (result, parser) { parser.pause();
const password = passGenerator.generate({
length: 6,
uppercase: false });
const name = result.data.name;
const email = result.data.email;
const certificateNumber = !result.data.certificateNumber ? null : result.data.certificateNumber;
const personAs = !result.data.personAs ? null : result.d ata.personAs;
const cekEmail = await User.findOne({ email: email });
if(cekEmail){
const ownerId = cekEmail._id;
certificate = new Certificate({ eventId, ownerId, ce rtificateNumber, personAs });
await certificate.save();
return parser.resume();
}
user = new User({ name, email, password });
const salt = await bcrypt.genSalt(10);
user.password = await bcrypt.hash(user.password, salt);
await user.save();
const ownerId = user._id;
certificate = new Certificate({ eventId, ownerId, certif icateNumber, personAs });
await certificate.save();
parser.resume();
},
Papaparse akan melakukan parsing data CSV ke dalam bentuk JSON per baris untuk memperoleh email, nama, nomor sertifikat dan peran peserta dalam event. Data
Gambar 4.16 Perbandingan data peserta CSV dengan hasil parsing.
Objek email dan name akan digunakan untuk mendaftarkan peserta yang belum terdaftar di sistem. Jika peserta telah terdaftar maka proses daftar tidak akan dilakukan dan data akan langsung disimpan ke database. Berikut adalah kode untuk menjelaskan bentuk dokumen sertifikat:
const certificateSchema = new mongoose.Schema({
eventId: {
type: mongoose.Schema.Types.ObjectId, ref: 'Event',
required: true },
ownerId: {
type: mongoose.Schema.Types.ObjectId, ref: 'User',
required: true },
certificateNumber: { type: String, default: null },
personAs: {
type: String, default: null },
url : {
type: String, default: null },
qrcode: {
type: String, default: null }
});
Berdasarkan kode di atas, objek eventID akan mereferensi objek _id pada collection event, dan objek ownerId akan mereferensi objek _id pada collection user.
Collection dalam MongoDB merupakan kumpulan dokumen. Dalam SQL collection dapat disamakan dengan sebuah tabel. Sedangkan dokumen pada MongoDB sama dengan baris pada tabel database SQL.
4.2.5 Proses Generate QR Code
Fungsi QR Code pada sistem ini adalah untuk menampung sebuah URL menuju halaman sertifikat. Halaman sertifikat ini berisi informasi terkait event dan pemilik sertifikat, sehingga dapat digunakan untuk membuktikan bahwa sertifikat tersebut memang benar dimiliki oleh user.
Penulis menggunakan server lokal (lokal) dalam pengembangan sistem sehingga URL ketika QR Code di-scan URL akan merujuk pada hostname localhost. Berikut adalah kode yang digunakan untuk men-generate URL untuk keperluan QR Code:
const certificateUrl = req.protocol + "://" + req.get('host') +
"/dashboard/certificate/" + certificate._id;
Sehingga didapatkan URL : http://localhost:3000/dashboard/certificate/
5e4371128e47f616d0023aa9. URL yang dihasilkan bersifat unik dikarenakan URL tersebut memiliki parameter _id dari masing-masing sertifikat. Untuk penjelasan tentang bagian-bagian URL dapat dilihat pada Gambar 4.17.
Gambar 4.17 Bagian-bagian URL.
Setelah URL didapatkan selanjutnya URL akan akan diubah ke dalam bentuk QR Code. Untuk proses ini penulis menggunakan libary qrcode untuk mengubah URL menjadi QR Code. Library qrcode menyediakan fungsi mengubah URL ke dalam bentuk QR Code, fungsi tersebut adalah toDataUrl(). Fungsi tersebut dapat mengubah string URL menjadi sebuah image/png. Untuk konfigurasinya penulis menggunakan correction level high yang dapat mentoleransi kesalahan scanning pada QR Code hingga 30%, tipe