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

test(desktop): add avro util test cases #1759

Merged
merged 1 commit into from
Sep 17, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
10 changes: 5 additions & 5 deletions src/utils/avro.ts
Original file line number Diff line number Diff line change
@@ -1,21 +1,21 @@
import * as avro from 'avsc'
import { convertObject } from './schemaUtils'

const validateSchema = (rawAvroSchema: string): avro.Type => {
export const parseSchema = (rawAvroSchema: string): avro.Type => {
let parsedSchema

try {
parsedSchema = JSON.parse(rawAvroSchema)
} catch (err) {
throw new Error(`Message serialization error: ${(err as Error).message}`)
throw new Error(`Schema not following JSON format: ${(err as Error).message}`)
}

return avro.Type.forSchema(parsedSchema)
}

export const checkAvroInput = (rawAvroSchema: string, input: string, format?: PayloadType): string => {
try {
const type: avro.Type = validateSchema(rawAvroSchema)
const type: avro.Type = parseSchema(rawAvroSchema)

type.isValid(JSON.parse(input), {
errorHook: (path, value, type) => {
Expand All @@ -34,7 +34,7 @@ export const checkAvroInput = (rawAvroSchema: string, input: string, format?: Pa
}

export const serializeAvroToBuffer = (raw: string, rawAvroSchema: string, format?: PayloadType): Buffer => {
const type: avro.Type = validateSchema(rawAvroSchema)
const type: avro.Type = parseSchema(rawAvroSchema)

let rawMessage: string
try {
Expand Down Expand Up @@ -64,7 +64,7 @@ export const deserializeBufferToAvro = (
rawAvroSchema: string,
needFormat?: PayloadType,
): Buffer | string => {
const type: avro.Type = validateSchema(rawAvroSchema)
const type: avro.Type = parseSchema(rawAvroSchema)

try {
const message = type.fromBuffer(payload)
Expand Down
97 changes: 97 additions & 0 deletions tests/unit/utils/avro.spec.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,97 @@
import { expect } from 'chai'
import { parseSchema, checkAvroInput, serializeAvroToBuffer, deserializeBufferToAvro } from '@/utils/avro'

import * as avro from 'avsc'

describe('Avro Utils', () => {
const mockSchema = `
{
"type": "record",
"name": "Person",
"fields": [
{"name": "id", "type": "int"},
{"name": "name", "type": "string"}
]
}
`

describe('parseSchema', () => {
it('should parse raw schema into avro type', () => {
const targetSchema = avro.Type.forSchema(JSON.parse(mockSchema))

const resultSchema = parseSchema(mockSchema)

expect(avro.Type.isType(resultSchema)).to.be.true
expect(targetSchema.equals(resultSchema)).to.be.true
})

it('should throw an error if raw schema does not follow JSON format', () => {
const invalidRawSchema = 'hello world!'
expect(() => parseSchema(invalidRawSchema)).to.throw('Schema not following JSON format: ')
})

it('should throw an error if raw schema does not fit avro schema pattern', () => {
const invalidAvroSchema = `
{
"type": "invalid",
"name": "TestRecord",
"fields": [
{ "name": "field1", "type": "string" }
]
}
`

expect(() => parseSchema(invalidAvroSchema)).to.throw('unknown type: "invalid"')
})
})

describe('checkAvroInput', () => {
it('should validate correct avro input', () => {
const correctInput = JSON.stringify({ id: 7, name: 'Last' })
const output = checkAvroInput(mockSchema, correctInput)

expect(output).to.be.a('string')
expect(output).to.include('7')
expect(output).to.include('Last')
})

it('should throw an error for invalid avro input', () => {
const invalidInput = JSON.stringify({ id: 4, name: 7 })

expect(() => checkAvroInput(mockSchema, invalidInput)).to.throw('Message Test Error at path')
})
})

describe('serializeAvroToBuffer', () => {
it('should serialize valid input to buffer', () => {
const correctInput = JSON.stringify({ id: 7, name: 'Carnival' })
const resultBuffer = serializeAvroToBuffer(correctInput, mockSchema)

expect(resultBuffer).to.be.instanceof(Buffer)
})

it('should throw error for invalid input', () => {
const invalidInput = JSON.stringify({ id: 'Last', name: 'Carnival' })
expect(() => serializeAvroToBuffer(invalidInput, mockSchema)).to.throw('Message serialization error:')
})
})

describe('deserializeBufferToAvro', () => {
it('should deserialize buffer to avro object', () => {
const schema = avro.Type.forSchema(JSON.parse(mockSchema))
const inputBuffer = schema.toBuffer({ id: 3, name: 'Skinandi' })

const result = deserializeBufferToAvro(inputBuffer, mockSchema)

expect(result).to.be.a('string')
expect(result).to.include('3')
expect(result).to.include('Skinandi')
})

it('should throw an error for invalid buffer', () => {
const randomeBuffer = Buffer.from([0x4f, 0x61, 0x7a, 0x3b, 0x19, 0x8e, 0x27, 0x56, 0x9c, 0x2d, 0x73, 0x81])

expect(() => deserializeBufferToAvro(randomeBuffer, mockSchema)).to.throw('Message deserialization error:')
})
})
})
Loading