Skip to content

Commit e0f3070

Browse files
committed
feat(repository): repo, connection, tests
1 parent 80e0eb2 commit e0f3070

32 files changed

+955
-182
lines changed

dist/package.json

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,8 @@
2929
"name": "Michael Yali",
3030
"email": "[email protected]"
3131
},
32-
"dependencies": {},
32+
"dependencies": {
33+
"@zmotivat0r/o0": "1.0.2"
34+
},
3335
"peerDependencies": {}
3436
}

e2e/__stubs__/cat.entity.ts

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
import { Entity } from '../../src/couchbase';
2+
import { config } from './config';
3+
4+
@Entity(config.bucket)
5+
export class Cat {
6+
name: string;
7+
}

e2e/__stubs__/config.ts

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
import { CouchbaseConnectionConfig } from '../../src/couchbase';
2+
3+
export const config: CouchbaseConnectionConfig = {
4+
url: 'couchbase://127.0.0.1',
5+
username: 'couchbase',
6+
password: 'couchbase',
7+
bucket: 'e2e_test',
8+
};
9+
10+
export const bucketOptions = { bucketType: 'ephemeral', replicaNumber: 0 };

e2e/__stubs__/index.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
export * from './config';
2+
export * from './cat.entity';

e2e/couchbase/couchbase.connection.factory.spec.ts

Lines changed: 78 additions & 42 deletions
Original file line numberDiff line numberDiff line change
@@ -1,59 +1,95 @@
1-
import { oO } from '@zmotivat0r/o0';
2-
import { Cluster } from 'couchbase';
3-
41
import { CouchbaseConnectionFactory } from '../../src/couchbase/couchbase.connection.factory';
5-
import { config } from '../../test/__stubs__';
2+
import { sleep } from '../../src/utils';
3+
import { config, bucketOptions } from '../__stubs__';
64

75
describe('#couchbase', () => {
86
describe('#CouchbaseConnectionFactory', () => {
9-
describe('#createCluster', () => {
7+
it('should be defined', () => {
8+
expect(CouchbaseConnectionFactory).toBeDefined();
9+
});
10+
11+
describe('#create', () => {
1012
it('should be defined', () => {
11-
expect(CouchbaseConnectionFactory.createCluster).toBeDefined();
13+
expect(CouchbaseConnectionFactory.create).toBeDefined();
1214
});
13-
it('should return cluster object', async () => {
14-
const [_, cluster] = await oO(CouchbaseConnectionFactory.createCluster(config));
15-
expect(cluster).toBeDefined();
16-
expect(cluster).toHaveProperty('auther');
15+
it('should create an instance', async () => {
16+
const conn = await CouchbaseConnectionFactory.create(config);
17+
expect(conn).toBeInstanceOf(CouchbaseConnectionFactory);
1718
});
18-
it('should return mocked cluster object', async () => {
19-
const [_, cluster] = await oO(
20-
CouchbaseConnectionFactory.createCluster({ ...config, mock: true }),
21-
);
22-
expect(cluster).toBeDefined();
23-
expect(cluster).toHaveProperty('dsnObj');
19+
it('should create an instance with mock', async () => {
20+
const conn = await CouchbaseConnectionFactory.create({ ...config, mock: true });
21+
expect(conn).toBeInstanceOf(CouchbaseConnectionFactory);
2422
});
2523
});
2624

27-
describe('#getBucket', () => {
28-
let cluster: Cluster;
25+
describe('#methods', () => {
26+
let conn: CouchbaseConnectionFactory;
27+
let mocked: CouchbaseConnectionFactory;
28+
29+
async function removeBuckets() {
30+
const [_, buckets] = await conn.listBuckets();
31+
if (buckets && buckets.length) {
32+
for (let i = 0; i < buckets.length; i++) {
33+
await conn.removeBucket(buckets[0].name);
34+
}
35+
}
36+
}
2937

3038
beforeAll(async () => {
31-
cluster = await CouchbaseConnectionFactory.createCluster(config);
39+
conn = await CouchbaseConnectionFactory.create(config);
40+
mocked = await CouchbaseConnectionFactory.create({ ...config, mock: true });
41+
await removeBuckets();
3242
});
3343

34-
it('should be defined', () => {
35-
expect(CouchbaseConnectionFactory.getBucket).toBeDefined();
36-
});
37-
it('should throw an error', async () => {
38-
const [err] = await oO(
39-
CouchbaseConnectionFactory.getBucket(cluster, { ...config, bucket: 'invalid' }),
40-
);
41-
expect(err).toBeInstanceOf(Error);
42-
});
43-
it('should return bucket object', async () => {
44-
const [_, bucket] = await oO(
45-
CouchbaseConnectionFactory.getBucket(cluster, config),
46-
);
47-
expect(bucket).toBeDefined();
48-
expect((bucket as any)._name).toBe('test');
49-
bucket.disconnect();
50-
});
51-
it('should return mocked bucket object', async () => {
52-
const [_, bucket] = await oO(
53-
CouchbaseConnectionFactory.getBucket(cluster, { ...config, mock: true }),
54-
);
55-
expect(bucket).toBeDefined();
56-
expect((bucket as any)._name).toBe('default');
44+
afterAll(async () => {
45+
await removeBuckets();
46+
});
47+
48+
describe('#createBucket', () => {
49+
it('should create a bucket', async () => {
50+
const [err, ok] = await conn.createBucket(config.bucket, bucketOptions);
51+
expect(err).toBeUndefined();
52+
expect(ok).toBe(true);
53+
await sleep(3500);
54+
});
55+
it('should return an error', async () => {
56+
const [err, _] = await conn.createBucket(config.bucket, bucketOptions);
57+
expect(err).toBeInstanceOf(Error);
58+
});
59+
});
60+
61+
describe('#listBuckets', () => {
62+
it('should return an array of buckets', async () => {
63+
const [_, buckets] = await conn.listBuckets();
64+
expect(Array.isArray(buckets)).toBe(true);
65+
});
66+
});
67+
68+
describe('#getBucket', () => {
69+
it('should return an error', async () => {
70+
const [err, _] = await conn.getBucket('invalid');
71+
expect(err).toBeInstanceOf(Error);
72+
});
73+
it('should return a bucket', async () => {
74+
const [_, bucket] = await conn.getBucket(config.bucket);
75+
expect(bucket).toBeDefined();
76+
bucket.disconnect();
77+
});
78+
it('should return a bucket with mock', async () => {
79+
const [_, bucket] = await mocked.getBucket(config.bucket);
80+
expect(bucket).toBeDefined();
81+
});
82+
});
83+
84+
describe('#removeBucket', () => {
85+
it('should return an error', async () => {
86+
const [err, _] = await conn.removeBucket('invalid');
87+
expect(err).toBeInstanceOf(Error);
88+
});
89+
it('should remove a bucket', async () => {
90+
const [_, ok] = await conn.removeBucket(config.bucket);
91+
expect(ok).toBe(true);
92+
});
5793
});
5894
});
5995
});
Lines changed: 83 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,83 @@
1+
import { CouchbaseConnectionFactory } from '../../src/couchbase/couchbase.connection.factory';
2+
import { CouchbaseRepositoryFactory } from '../../src/couchbase/couchbase.repository.factory';
3+
import { CouchbaseException } from '../../src/couchbase/exceptions/couchbase.exception';
4+
import { Entity } from '../../src/couchbase/decorators/entity.decorator';
5+
import { sleep, flattenPromise } from '../../src/utils';
6+
import { config, bucketOptions, Cat } from '../__stubs__';
7+
8+
describe('#couchbase', () => {
9+
describe('#CouchbaseRepositoryFactory', () => {
10+
it('should be defined', () => {
11+
expect(CouchbaseRepositoryFactory).toBeDefined();
12+
});
13+
14+
let conn: CouchbaseConnectionFactory;
15+
let mocked: CouchbaseConnectionFactory;
16+
17+
async function removeBuckets() {
18+
const [_, buckets] = await conn.listBuckets();
19+
if (buckets && buckets.length) {
20+
for (let i = 0; i < buckets.length; i++) {
21+
await conn.removeBucket(buckets[0].name);
22+
}
23+
}
24+
}
25+
26+
beforeAll(async () => {
27+
conn = await CouchbaseConnectionFactory.create(config);
28+
mocked = await CouchbaseConnectionFactory.create({ ...config, mock: true });
29+
await removeBuckets();
30+
await conn.createBucket(config.bucket, bucketOptions);
31+
await sleep(3500);
32+
});
33+
34+
afterAll(async () => {
35+
const [_, bucket] = await conn.getBucket(config.bucket);
36+
bucket.disconnect();
37+
await removeBuckets();
38+
});
39+
40+
describe('#create', () => {
41+
it('should be defined', () => {
42+
expect(CouchbaseRepositoryFactory.create).toBeDefined();
43+
});
44+
it('should throw an error, 1', async () => {
45+
const [err] = await flattenPromise(CouchbaseRepositoryFactory.create)();
46+
expect(err).toBeInstanceOf(Error);
47+
});
48+
it('should throw an error, 2', async () => {
49+
const [err] = await flattenPromise(CouchbaseRepositoryFactory.create)(conn);
50+
expect(err).toBeInstanceOf(Error);
51+
});
52+
it('should throw an error, 3', async () => {
53+
class InvalidTestEntity {}
54+
const [err] = await flattenPromise(CouchbaseRepositoryFactory.create)(
55+
conn,
56+
InvalidTestEntity,
57+
);
58+
expect(err).toBeInstanceOf(CouchbaseException);
59+
});
60+
it('should throw an error, 4', async () => {
61+
@Entity('invalid')
62+
class InvalidTestEntity {}
63+
const [err] = await flattenPromise(CouchbaseRepositoryFactory.create)(
64+
conn,
65+
InvalidTestEntity,
66+
);
67+
expect(err).toBeInstanceOf(Error);
68+
});
69+
it('should create new Repository', async () => {
70+
const repo = await CouchbaseRepositoryFactory.create(conn, Cat);
71+
expect(repo).toBeDefined();
72+
expect(typeof repo).toBe('object');
73+
expect(repo.entity).toBeDefined();
74+
});
75+
it('should create new Repository with mock', async () => {
76+
const repo = await CouchbaseRepositoryFactory.create(mocked, Cat);
77+
expect(repo).toBeDefined();
78+
expect(typeof repo).toBe('object');
79+
expect(repo.entity).toBeDefined();
80+
});
81+
});
82+
});
83+
});
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
import { CouchbaseConnectionFactory } from '../../src/couchbase/couchbase.connection.factory';

integration/app.module.ts

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
import { Module } from '@nestjs/common';
2+
3+
import { CouchbaseModule } from '../src/module';
4+
import { UsersModule } from './users';
5+
import { config } from './couchbase.config';
6+
7+
@Module({
8+
imports: [CouchbaseModule.forRoot(config), UsersModule],
9+
})
10+
export class AppModule {}

integration/couchbase.config.ts

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
import { CouchbaseConnectionConfig } from '../src/couchbase';
2+
3+
export const config: CouchbaseConnectionConfig = {
4+
url: 'couchbase://127.0.0.1',
5+
username: 'couchbase',
6+
password: 'couchbase',
7+
bucket: 'test',
8+
};
Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
import {
2+
ExceptionFilter,
3+
Catch,
4+
ArgumentsHost,
5+
HttpException,
6+
InternalServerErrorException,
7+
} from '@nestjs/common';
8+
9+
@Catch()
10+
export class HttpExceptionFilter implements ExceptionFilter {
11+
catch(exception: HttpException, host: ArgumentsHost) {
12+
const ctx = host.switchToHttp();
13+
const response = ctx.getResponse();
14+
const { status, json } = this.prepareException(exception);
15+
16+
response.status(status).send(json);
17+
}
18+
19+
prepareException(exc: any): { status: number; json: object } {
20+
const error =
21+
exc instanceof HttpException ? exc : new InternalServerErrorException(exc.message);
22+
const status = error.getStatus();
23+
const response = error.getResponse();
24+
const json = typeof response === 'string' ? { error: response } : response;
25+
26+
return { status, json };
27+
}
28+
}

0 commit comments

Comments
 (0)