|
@@ -0,0 +1,194 @@
|
|
|
+import {
|
|
|
+ it,
|
|
|
+ describe,
|
|
|
+} from 'mocha'
|
|
|
+import {
|
|
|
+ Connection,
|
|
|
+ Keypair,
|
|
|
+ PublicKey,
|
|
|
+ sendAndConfirmTransaction,
|
|
|
+ SystemProgram,
|
|
|
+ Transaction,
|
|
|
+} from '@solana/web3.js'
|
|
|
+import {
|
|
|
+ AddCarArgs,
|
|
|
+ Car,
|
|
|
+ RentalOrder,
|
|
|
+ RentalOrderStatus,
|
|
|
+ createAddCarInstruction,
|
|
|
+ createBookRentalInstruction,
|
|
|
+ createPickUpCarInstruction,
|
|
|
+ createReturnCarInstruction,
|
|
|
+} from './generated'
|
|
|
+
|
|
|
+
|
|
|
+function loadKeypairFromFile(path: string): Keypair {
|
|
|
+ return Keypair.fromSecretKey(
|
|
|
+ Buffer.from(JSON.parse(require('fs').readFileSync(path, "utf-8")))
|
|
|
+ )
|
|
|
+}
|
|
|
+
|
|
|
+const carBmw: AddCarArgs = {
|
|
|
+ year: 2020,
|
|
|
+ make: 'BMW',
|
|
|
+ model: 'iX1',
|
|
|
+}
|
|
|
+
|
|
|
+const carMercedes: AddCarArgs = {
|
|
|
+ year: 2019,
|
|
|
+ make: 'Mercedes-Benz',
|
|
|
+ model: 'EQS',
|
|
|
+}
|
|
|
+
|
|
|
+const rentalInfo = {
|
|
|
+ name: "Fred Flinstone",
|
|
|
+ pickUpDate: "01/28/2023 8:00 AM",
|
|
|
+ returnDate: "01/28/2023 10:00 PM",
|
|
|
+ price: 300,
|
|
|
+}
|
|
|
+
|
|
|
+
|
|
|
+describe("Car Rental Service", () => {
|
|
|
+
|
|
|
+ const connection = new Connection(`https://api.devnet.solana.com`, 'confirmed')
|
|
|
+ const payer = loadKeypairFromFile(require('os').homedir() + '/.config/solana/id.json')
|
|
|
+ const program = loadKeypairFromFile('./program/target/deploy/car_rental_service-keypair.json')
|
|
|
+
|
|
|
+ let bmwPublicKey: PublicKey
|
|
|
+ let mercedesPublicKey: PublicKey
|
|
|
+
|
|
|
+ async function createCar(car: AddCarArgs): Promise<PublicKey> {
|
|
|
+ const carAccountPublicKey = PublicKey.findProgramAddressSync(
|
|
|
+ [
|
|
|
+ Buffer.from('car'),
|
|
|
+ Buffer.from(car.make),
|
|
|
+ Buffer.from(car.model),
|
|
|
+ ],
|
|
|
+ program.publicKey,
|
|
|
+ )[0]
|
|
|
+ const ix = createAddCarInstruction(
|
|
|
+ {
|
|
|
+ carAccount: carAccountPublicKey,
|
|
|
+ payer: payer.publicKey,
|
|
|
+ systemProgram: SystemProgram.programId,
|
|
|
+ },
|
|
|
+ { addCarArgs: { ...car } },
|
|
|
+ )
|
|
|
+ const sx = await sendAndConfirmTransaction(
|
|
|
+ connection,
|
|
|
+ new Transaction().add(ix),
|
|
|
+ [payer],
|
|
|
+ { skipPreflight: true }
|
|
|
+ )
|
|
|
+ await connection.confirmTransaction(sx)
|
|
|
+ const carData = await Car.fromAccountAddress(connection, carAccountPublicKey)
|
|
|
+ console.log('New car created:')
|
|
|
+ console.log(` Year : ${carData.year}`)
|
|
|
+ console.log(` Make : ${carData.make}`)
|
|
|
+ console.log(` Model : ${carData.model}`)
|
|
|
+ return carAccountPublicKey
|
|
|
+ }
|
|
|
+ it("Create a car that can be rented", async () => { bmwPublicKey = await createCar(carBmw) })
|
|
|
+ it("Create another car that can be rented", async () => { mercedesPublicKey = await createCar(carMercedes) })
|
|
|
+
|
|
|
+ const evaluateStatus = (status: RentalOrderStatus): string => {
|
|
|
+ if (status === RentalOrderStatus.Created) return "Created"
|
|
|
+ if (status === RentalOrderStatus.PickedUp) return "Picked Up"
|
|
|
+ return "Returned"
|
|
|
+ }
|
|
|
+
|
|
|
+ async function printRentalDetails(rentalPublicKey: PublicKey, carPublicKey: PublicKey) {
|
|
|
+ const rentalData = await RentalOrder.fromAccountAddress(connection, rentalPublicKey)
|
|
|
+ const carData = await Car.fromAccountAddress(connection, carPublicKey)
|
|
|
+ console.log('Rental booked:')
|
|
|
+ console.log(' Vehicle details:')
|
|
|
+ console.log(` Year : ${carData.year}`)
|
|
|
+ console.log(` Make : ${carData.make}`)
|
|
|
+ console.log(` Model : ${carData.model}`)
|
|
|
+ console.log(` Name : ${rentalData.name}`)
|
|
|
+ console.log(` Pick Up : ${rentalData.pickUpDate}`)
|
|
|
+ console.log(` Return : ${rentalData.returnDate}`)
|
|
|
+ console.log(` Price : ${rentalData.price}`)
|
|
|
+ console.log(` Status : ${evaluateStatus(rentalData.status)}`)
|
|
|
+ }
|
|
|
+
|
|
|
+ it("Book a new rental", async () => {
|
|
|
+ const rentalAccountPublicKey = PublicKey.findProgramAddressSync(
|
|
|
+ [
|
|
|
+ Buffer.from('rental_order'),
|
|
|
+ bmwPublicKey.toBuffer(),
|
|
|
+ payer.publicKey.toBuffer(),
|
|
|
+ ],
|
|
|
+ program.publicKey,
|
|
|
+ )[0]
|
|
|
+ const ix = createBookRentalInstruction(
|
|
|
+ {
|
|
|
+ rentalAccount: rentalAccountPublicKey,
|
|
|
+ carAccount: bmwPublicKey,
|
|
|
+ payer: payer.publicKey,
|
|
|
+ systemProgram: SystemProgram.programId,
|
|
|
+ },
|
|
|
+ {
|
|
|
+ bookRentalArgs: { ...rentalInfo }
|
|
|
+ },
|
|
|
+ )
|
|
|
+ const sx = await sendAndConfirmTransaction(
|
|
|
+ connection,
|
|
|
+ new Transaction().add(ix),
|
|
|
+ [payer]
|
|
|
+ )
|
|
|
+ await connection.confirmTransaction(sx)
|
|
|
+ await printRentalDetails(rentalAccountPublicKey, bmwPublicKey)
|
|
|
+ })
|
|
|
+
|
|
|
+ it("Pick up your rental car", async () => {
|
|
|
+ const rentalAccountPublicKey = PublicKey.findProgramAddressSync(
|
|
|
+ [
|
|
|
+ Buffer.from('rental_order'),
|
|
|
+ bmwPublicKey.toBuffer(),
|
|
|
+ payer.publicKey.toBuffer(),
|
|
|
+ ],
|
|
|
+ program.publicKey,
|
|
|
+ )[0]
|
|
|
+ const ix = createPickUpCarInstruction(
|
|
|
+ {
|
|
|
+ rentalAccount: rentalAccountPublicKey,
|
|
|
+ carAccount: bmwPublicKey,
|
|
|
+ payer: payer.publicKey,
|
|
|
+ }
|
|
|
+ )
|
|
|
+ const sx = await sendAndConfirmTransaction(
|
|
|
+ connection,
|
|
|
+ new Transaction().add(ix),
|
|
|
+ [payer]
|
|
|
+ )
|
|
|
+ await connection.confirmTransaction(sx)
|
|
|
+ await printRentalDetails(rentalAccountPublicKey, bmwPublicKey)
|
|
|
+ })
|
|
|
+
|
|
|
+ it("Return your rental car", async () => {
|
|
|
+ const rentalAccountPublicKey = PublicKey.findProgramAddressSync(
|
|
|
+ [
|
|
|
+ Buffer.from('rental_order'),
|
|
|
+ bmwPublicKey.toBuffer(),
|
|
|
+ payer.publicKey.toBuffer(),
|
|
|
+ ],
|
|
|
+ program.publicKey,
|
|
|
+ )[0]
|
|
|
+ const ix = createReturnCarInstruction(
|
|
|
+ {
|
|
|
+ rentalAccount: rentalAccountPublicKey,
|
|
|
+ carAccount: bmwPublicKey,
|
|
|
+ payer: payer.publicKey,
|
|
|
+ }
|
|
|
+ )
|
|
|
+ const sx = await sendAndConfirmTransaction(
|
|
|
+ connection,
|
|
|
+ new Transaction().add(ix),
|
|
|
+ [payer]
|
|
|
+ )
|
|
|
+ await connection.confirmTransaction(sx)
|
|
|
+ await printRentalDetails(rentalAccountPublicKey, bmwPublicKey)
|
|
|
+ })
|
|
|
+ })
|
|
|
+
|