Add Routes to application
This commit is contained in:
parent
f0943cfe80
commit
2ed3aeac26
@ -8,7 +8,6 @@ export interface ICommentProps {
|
|||||||
export class CommentVote extends React.PureComponent {
|
export class CommentVote extends React.PureComponent {
|
||||||
render() {
|
render() {
|
||||||
return (
|
return (
|
||||||
|
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,8 +1,7 @@
|
|||||||
import assert from 'assert'
|
|
||||||
import axios from 'axios'
|
import axios from 'axios'
|
||||||
import {IHTTPClient} from './IHTTPClient'
|
import {IHTTPClient} from './IHTTPClient'
|
||||||
import {IHeader} from './IHeader'
|
import {IHeader} from './IHeader'
|
||||||
import {IMethod, IRoutes} from '@rondo/common'
|
import {IMethod, IRoutes, URLFormatter} from '@rondo/common'
|
||||||
import {IRequest} from './IRequest'
|
import {IRequest} from './IRequest'
|
||||||
import {IResponse} from './IResponse'
|
import {IResponse} from './IResponse'
|
||||||
import {ITypedRequestParams} from './ITypedRequestParams'
|
import {ITypedRequestParams} from './ITypedRequestParams'
|
||||||
@ -13,12 +12,14 @@ interface IRequestor {
|
|||||||
|
|
||||||
export class HTTPClient<T extends IRoutes> implements IHTTPClient<T> {
|
export class HTTPClient<T extends IRoutes> implements IHTTPClient<T> {
|
||||||
protected readonly requestor: IRequestor
|
protected readonly requestor: IRequestor
|
||||||
|
protected readonly formatter: URLFormatter
|
||||||
|
|
||||||
constructor(
|
constructor(
|
||||||
protected readonly baseURL = '',
|
protected readonly baseURL = '',
|
||||||
protected readonly headers?: IHeader,
|
protected readonly headers?: IHeader,
|
||||||
) {
|
) {
|
||||||
this.requestor = this.createRequestor()
|
this.requestor = this.createRequestor()
|
||||||
|
this.formatter = new URLFormatter()
|
||||||
}
|
}
|
||||||
|
|
||||||
protected createRequestor(): IRequestor {
|
protected createRequestor(): IRequestor {
|
||||||
@ -33,12 +34,7 @@ export class HTTPClient<T extends IRoutes> implements IHTTPClient<T> {
|
|||||||
M extends IMethod,
|
M extends IMethod,
|
||||||
>(params: ITypedRequestParams<T, P, M>): Promise<T[P][M]['response']> {
|
>(params: ITypedRequestParams<T, P, M>): Promise<T[P][M]['response']> {
|
||||||
|
|
||||||
const url = params.path.replace(/:[a-zA-Z0-9-]+/g, (match) => {
|
const url = this.formatter.format(params.path, params.params)
|
||||||
const key = match.substring(1)
|
|
||||||
assert(params.params, 'Params is required, but not defined')
|
|
||||||
assert(params.params!.hasOwnProperty(key))
|
|
||||||
return params.params![key]
|
|
||||||
})
|
|
||||||
|
|
||||||
const response = await this.requestor.request({
|
const response = await this.requestor.request({
|
||||||
method: params.method,
|
method: params.method,
|
||||||
|
|||||||
3
packages/common/src/IRequestParams.ts
Normal file
3
packages/common/src/IRequestParams.ts
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
export interface IRequestParams {
|
||||||
|
[key: string]: string | number
|
||||||
|
}
|
||||||
27
packages/common/src/URLFormatter.ts
Normal file
27
packages/common/src/URLFormatter.ts
Normal file
@ -0,0 +1,27 @@
|
|||||||
|
import assert from 'assert'
|
||||||
|
import {IRequestParams} from './IRequestParams'
|
||||||
|
|
||||||
|
export interface IURLFormatterOptions {
|
||||||
|
readonly baseURL: string
|
||||||
|
readonly regex: RegExp
|
||||||
|
}
|
||||||
|
|
||||||
|
export class URLFormatter {
|
||||||
|
constructor(readonly params: IURLFormatterOptions = {
|
||||||
|
baseURL: '',
|
||||||
|
regex: /:[a-zA-Z0-9-]+/g,
|
||||||
|
}) {}
|
||||||
|
|
||||||
|
format(url: string, params?: IRequestParams) {
|
||||||
|
if (!params) {
|
||||||
|
return url
|
||||||
|
}
|
||||||
|
const formattedUrl = url.replace(this.params.regex, match => {
|
||||||
|
const key = match.substring(1)
|
||||||
|
assert(params.hasOwnProperty(key))
|
||||||
|
return String(params![key])
|
||||||
|
})
|
||||||
|
|
||||||
|
return this.params.baseURL + formattedUrl
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -3,6 +3,8 @@ export * from './IComment'
|
|||||||
export * from './ICommentTree'
|
export * from './ICommentTree'
|
||||||
export * from './ICredentials'
|
export * from './ICredentials'
|
||||||
export * from './IRoutes'
|
export * from './IRoutes'
|
||||||
|
export * from './IRequestParams'
|
||||||
export * from './ISite'
|
export * from './ISite'
|
||||||
export * from './ITeam'
|
export * from './ITeam'
|
||||||
export * from './IUser'
|
export * from './IUser'
|
||||||
|
export * from './URLFormatter'
|
||||||
|
|||||||
@ -8,7 +8,7 @@ import {IDatabase} from '../database/IDatabase'
|
|||||||
import {ILogger} from '../logger/ILogger'
|
import {ILogger} from '../logger/ILogger'
|
||||||
import {IRoutes} from '@rondo/common'
|
import {IRoutes} from '@rondo/common'
|
||||||
import {ITransactionManager} from '../database/ITransactionManager'
|
import {ITransactionManager} from '../database/ITransactionManager'
|
||||||
import {IUserService, UserService} from '../services'
|
import * as services from '../services'
|
||||||
import {loggerFactory, LoggerFactory} from '../logger/LoggerFactory'
|
import {loggerFactory, LoggerFactory} from '../logger/LoggerFactory'
|
||||||
import {urlencoded, json} from 'body-parser'
|
import {urlencoded, json} from 'body-parser'
|
||||||
|
|
||||||
@ -16,14 +16,26 @@ export class Application implements IApplication {
|
|||||||
readonly transactionManager: ITransactionManager
|
readonly transactionManager: ITransactionManager
|
||||||
readonly server: express.Application
|
readonly server: express.Application
|
||||||
|
|
||||||
readonly userService: IUserService
|
readonly userService: services.IUserService
|
||||||
|
readonly teamService: services.ITeamService
|
||||||
|
readonly siteService: services.ISiteService
|
||||||
|
readonly storyService: services.IStoryService
|
||||||
|
readonly commentService: services.ICommentService
|
||||||
|
|
||||||
readonly authenticator: middleware.Authenticator
|
readonly authenticator: middleware.Authenticator
|
||||||
|
|
||||||
readonly loggerFactory: LoggerFactory = loggerFactory
|
readonly loggerFactory: LoggerFactory = loggerFactory
|
||||||
|
|
||||||
constructor(readonly config: IConfig, readonly database: IDatabase) {
|
constructor(readonly config: IConfig, readonly database: IDatabase) {
|
||||||
this.transactionManager = database.transactionManager
|
this.transactionManager = database.transactionManager
|
||||||
this.userService = new UserService(this.transactionManager)
|
this.userService = new services.UserService(this.transactionManager)
|
||||||
|
|
||||||
|
this.teamService = new services.TeamService(this.transactionManager)
|
||||||
|
this.siteService = new services.SiteService(this.transactionManager)
|
||||||
|
this.storyService = new services.StoryService(
|
||||||
|
this.transactionManager, this.siteService)
|
||||||
|
this.commentService = new services.CommentService(this.transactionManager)
|
||||||
|
|
||||||
this.authenticator = new middleware.Authenticator(this.userService)
|
this.authenticator = new middleware.Authenticator(this.userService)
|
||||||
|
|
||||||
this.server = this.createServer()
|
this.server = this.createServer()
|
||||||
@ -78,11 +90,32 @@ export class Application implements IApplication {
|
|||||||
router.use('/app', routes.application)
|
router.use('/app', routes.application)
|
||||||
|
|
||||||
router.use('/api', json())
|
router.use('/api', json())
|
||||||
|
|
||||||
router.use('/api', new routes.UserRoutes(
|
router.use('/api', new routes.UserRoutes(
|
||||||
this.userService,
|
this.userService,
|
||||||
this.createTransactionalRouter(),
|
this.createTransactionalRouter(),
|
||||||
).handle)
|
).handle)
|
||||||
|
|
||||||
|
router.use('/api', new routes.TeamRoutes(
|
||||||
|
this.teamService,
|
||||||
|
this.createTransactionalRouter(),
|
||||||
|
).handle)
|
||||||
|
|
||||||
|
router.use('/api', new routes.SiteRoutes(
|
||||||
|
this.siteService,
|
||||||
|
this.createTransactionalRouter(),
|
||||||
|
).handle)
|
||||||
|
|
||||||
|
router.use('/api', new routes.StoryRoutes(
|
||||||
|
this.storyService,
|
||||||
|
this.createTransactionalRouter(),
|
||||||
|
).handle)
|
||||||
|
|
||||||
|
router.use('/api', new routes.CommentRoutes(
|
||||||
|
this.commentService,
|
||||||
|
this.createTransactionalRouter(),
|
||||||
|
).handle)
|
||||||
|
|
||||||
router.use('/api', new middleware.ErrorApiHandler(apiLogger).handle)
|
router.use('/api', new middleware.ErrorApiHandler(apiLogger).handle)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -14,7 +14,6 @@ export class Team extends BaseEntity {
|
|||||||
userId!: number
|
userId!: number
|
||||||
|
|
||||||
@ManyToOne(type => User)
|
@ManyToOne(type => User)
|
||||||
@Column()
|
|
||||||
user?: User
|
user?: User
|
||||||
|
|
||||||
@OneToMany(type => Site, site => site.team)
|
@OneToMany(type => Site, site => site.team)
|
||||||
|
|||||||
101
packages/server/src/migrations/1548347305012-indices.ts
Normal file
101
packages/server/src/migrations/1548347305012-indices.ts
Normal file
@ -0,0 +1,101 @@
|
|||||||
|
import {MigrationInterface, QueryRunner} from "typeorm";
|
||||||
|
|
||||||
|
export class test1548347305012 implements MigrationInterface {
|
||||||
|
|
||||||
|
public async up(queryRunner: QueryRunner): Promise<any> {
|
||||||
|
await queryRunner.query(`DROP INDEX "IDX_28c5d1d16da7908c97c9bc2f74"`);
|
||||||
|
await queryRunner.query(`DROP INDEX "IDX_fe13edd1431a248a0eeac11ae4"`);
|
||||||
|
await queryRunner.query(`CREATE TABLE "temporary_spam" ("id" integer PRIMARY KEY AUTOINCREMENT NOT NULL, "createDate" datetime NOT NULL DEFAULT (datetime('now')), "updateDate" datetime NOT NULL DEFAULT (datetime('now')), "userId" integer NOT NULL, "commentId" integer NOT NULL, CONSTRAINT "FK_ec8bc4fa789466cf62f5949f5cc" FOREIGN KEY ("userId") REFERENCES "user" ("id") ON DELETE NO ACTION ON UPDATE NO ACTION, CONSTRAINT "FK_1bf468db8f4d18b424bb3eafae5" FOREIGN KEY ("commentId") REFERENCES "comment" ("id") ON DELETE NO ACTION ON UPDATE NO ACTION)`);
|
||||||
|
await queryRunner.query(`INSERT INTO "temporary_spam"("id", "createDate", "updateDate", "userId", "commentId") SELECT "id", "createDate", "updateDate", "userId", "commentId" FROM "spam"`);
|
||||||
|
await queryRunner.query(`DROP TABLE "spam"`);
|
||||||
|
await queryRunner.query(`ALTER TABLE "temporary_spam" RENAME TO "spam"`);
|
||||||
|
await queryRunner.query(`CREATE TABLE "temporary_vote" ("id" integer PRIMARY KEY AUTOINCREMENT NOT NULL, "createDate" datetime NOT NULL DEFAULT (datetime('now')), "updateDate" datetime NOT NULL DEFAULT (datetime('now')), "userId" integer NOT NULL, "commentId" integer NOT NULL, CONSTRAINT "FK_f5de237a438d298031d11a57c3b" FOREIGN KEY ("userId") REFERENCES "user" ("id") ON DELETE NO ACTION ON UPDATE NO ACTION, CONSTRAINT "FK_ad37adcff60fdb9670a97868ab1" FOREIGN KEY ("commentId") REFERENCES "comment" ("id") ON DELETE NO ACTION ON UPDATE NO ACTION)`);
|
||||||
|
await queryRunner.query(`INSERT INTO "temporary_vote"("id", "createDate", "updateDate", "userId", "commentId") SELECT "id", "createDate", "updateDate", "userId", "commentId" FROM "vote"`);
|
||||||
|
await queryRunner.query(`DROP TABLE "vote"`);
|
||||||
|
await queryRunner.query(`ALTER TABLE "temporary_vote" RENAME TO "vote"`);
|
||||||
|
await queryRunner.query(`CREATE TABLE "temporary_site" ("id" integer PRIMARY KEY AUTOINCREMENT NOT NULL, "createDate" datetime NOT NULL DEFAULT (datetime('now')), "updateDate" datetime NOT NULL DEFAULT (datetime('now')), "name" varchar NOT NULL, "domain" varchar NOT NULL, "userId" integer NOT NULL, "teamId" integer NOT NULL, CONSTRAINT "FK_4a06baede7d9cf51aef879fb0e4" FOREIGN KEY ("teamId") REFERENCES "team" ("id") ON DELETE NO ACTION ON UPDATE NO ACTION, CONSTRAINT "FK_e03827c061fbf85fd3aae454aec" FOREIGN KEY ("userId") REFERENCES "user" ("id") ON DELETE NO ACTION ON UPDATE NO ACTION)`);
|
||||||
|
await queryRunner.query(`INSERT INTO "temporary_site"("id", "createDate", "updateDate", "name", "domain", "userId", "teamId") SELECT "id", "createDate", "updateDate", "name", "domain", "userId", "teamId" FROM "site"`);
|
||||||
|
await queryRunner.query(`DROP TABLE "site"`);
|
||||||
|
await queryRunner.query(`ALTER TABLE "temporary_site" RENAME TO "site"`);
|
||||||
|
await queryRunner.query(`CREATE TABLE "temporary_team" ("id" integer PRIMARY KEY AUTOINCREMENT NOT NULL, "createDate" datetime NOT NULL DEFAULT (datetime('now')), "updateDate" datetime NOT NULL DEFAULT (datetime('now')))`);
|
||||||
|
await queryRunner.query(`INSERT INTO "temporary_team"("id", "createDate", "updateDate") SELECT "id", "createDate", "updateDate" FROM "team"`);
|
||||||
|
await queryRunner.query(`DROP TABLE "team"`);
|
||||||
|
await queryRunner.query(`ALTER TABLE "temporary_team" RENAME TO "team"`);
|
||||||
|
await queryRunner.query(`CREATE TABLE "temporary_team" ("id" integer PRIMARY KEY AUTOINCREMENT NOT NULL, "createDate" datetime NOT NULL DEFAULT (datetime('now')), "updateDate" datetime NOT NULL DEFAULT (datetime('now')), "name" varchar NOT NULL, "userId" integer NOT NULL)`);
|
||||||
|
await queryRunner.query(`INSERT INTO "temporary_team"("id", "createDate", "updateDate") SELECT "id", "createDate", "updateDate" FROM "team"`);
|
||||||
|
await queryRunner.query(`DROP TABLE "team"`);
|
||||||
|
await queryRunner.query(`ALTER TABLE "temporary_team" RENAME TO "team"`);
|
||||||
|
await queryRunner.query(`CREATE TABLE "temporary_site" ("id" integer PRIMARY KEY AUTOINCREMENT NOT NULL, "createDate" datetime NOT NULL DEFAULT (datetime('now')), "updateDate" datetime NOT NULL DEFAULT (datetime('now')), "name" varchar NOT NULL, "domain" varchar NOT NULL, "userId" integer NOT NULL, "teamId" integer NOT NULL, CONSTRAINT "UQ_a8c109f03677d373ab0256f82c6" UNIQUE ("domain"), CONSTRAINT "FK_4a06baede7d9cf51aef879fb0e4" FOREIGN KEY ("teamId") REFERENCES "team" ("id") ON DELETE NO ACTION ON UPDATE NO ACTION, CONSTRAINT "FK_e03827c061fbf85fd3aae454aec" FOREIGN KEY ("userId") REFERENCES "user" ("id") ON DELETE NO ACTION ON UPDATE NO ACTION)`);
|
||||||
|
await queryRunner.query(`INSERT INTO "temporary_site"("id", "createDate", "updateDate", "name", "domain", "userId", "teamId") SELECT "id", "createDate", "updateDate", "name", "domain", "userId", "teamId" FROM "site"`);
|
||||||
|
await queryRunner.query(`DROP TABLE "site"`);
|
||||||
|
await queryRunner.query(`ALTER TABLE "temporary_site" RENAME TO "site"`);
|
||||||
|
await queryRunner.query(`CREATE INDEX "IDX_28c5d1d16da7908c97c9bc2f74" ON "session" ("expiredAt") `);
|
||||||
|
await queryRunner.query(`CREATE INDEX "IDX_55a938fda82579fd3ec29b3c28" ON "team" ("userId") `);
|
||||||
|
await queryRunner.query(`CREATE INDEX "IDX_e03827c061fbf85fd3aae454ae" ON "site" ("userId") `);
|
||||||
|
await queryRunner.query(`CREATE INDEX "IDX_4a06baede7d9cf51aef879fb0e" ON "site" ("teamId") `);
|
||||||
|
await queryRunner.query(`CREATE INDEX "IDX_fe13edd1431a248a0eeac11ae4" ON "comment" ("storyId") `);
|
||||||
|
await queryRunner.query(`CREATE TABLE "temporary_spam" ("id" integer PRIMARY KEY AUTOINCREMENT NOT NULL, "createDate" datetime NOT NULL DEFAULT (datetime('now')), "updateDate" datetime NOT NULL DEFAULT (datetime('now')), "userId" integer NOT NULL, "commentId" integer NOT NULL, CONSTRAINT "spam_userid_commentid" UNIQUE ("userId", "commentId"), CONSTRAINT "FK_ec8bc4fa789466cf62f5949f5cc" FOREIGN KEY ("userId") REFERENCES "user" ("id") ON DELETE NO ACTION ON UPDATE NO ACTION, CONSTRAINT "FK_1bf468db8f4d18b424bb3eafae5" FOREIGN KEY ("commentId") REFERENCES "comment" ("id") ON DELETE NO ACTION ON UPDATE NO ACTION)`);
|
||||||
|
await queryRunner.query(`INSERT INTO "temporary_spam"("id", "createDate", "updateDate", "userId", "commentId") SELECT "id", "createDate", "updateDate", "userId", "commentId" FROM "spam"`);
|
||||||
|
await queryRunner.query(`DROP TABLE "spam"`);
|
||||||
|
await queryRunner.query(`ALTER TABLE "temporary_spam" RENAME TO "spam"`);
|
||||||
|
await queryRunner.query(`CREATE TABLE "temporary_vote" ("id" integer PRIMARY KEY AUTOINCREMENT NOT NULL, "createDate" datetime NOT NULL DEFAULT (datetime('now')), "updateDate" datetime NOT NULL DEFAULT (datetime('now')), "userId" integer NOT NULL, "commentId" integer NOT NULL, CONSTRAINT "vote_userid_commentid" UNIQUE ("userId", "commentId"), CONSTRAINT "FK_f5de237a438d298031d11a57c3b" FOREIGN KEY ("userId") REFERENCES "user" ("id") ON DELETE NO ACTION ON UPDATE NO ACTION, CONSTRAINT "FK_ad37adcff60fdb9670a97868ab1" FOREIGN KEY ("commentId") REFERENCES "comment" ("id") ON DELETE NO ACTION ON UPDATE NO ACTION)`);
|
||||||
|
await queryRunner.query(`INSERT INTO "temporary_vote"("id", "createDate", "updateDate", "userId", "commentId") SELECT "id", "createDate", "updateDate", "userId", "commentId" FROM "vote"`);
|
||||||
|
await queryRunner.query(`DROP TABLE "vote"`);
|
||||||
|
await queryRunner.query(`ALTER TABLE "temporary_vote" RENAME TO "vote"`);
|
||||||
|
await queryRunner.query(`DROP INDEX "IDX_55a938fda82579fd3ec29b3c28"`);
|
||||||
|
await queryRunner.query(`CREATE TABLE "temporary_team" ("id" integer PRIMARY KEY AUTOINCREMENT NOT NULL, "createDate" datetime NOT NULL DEFAULT (datetime('now')), "updateDate" datetime NOT NULL DEFAULT (datetime('now')), "name" varchar NOT NULL, "userId" integer NOT NULL, CONSTRAINT "FK_55a938fda82579fd3ec29b3c28e" FOREIGN KEY ("userId") REFERENCES "user" ("id"))`);
|
||||||
|
await queryRunner.query(`INSERT INTO "temporary_team"("id", "createDate", "updateDate", "name", "userId") SELECT "id", "createDate", "updateDate", "name", "userId" FROM "team"`);
|
||||||
|
await queryRunner.query(`DROP TABLE "team"`);
|
||||||
|
await queryRunner.query(`ALTER TABLE "temporary_team" RENAME TO "team"`);
|
||||||
|
await queryRunner.query(`CREATE INDEX "IDX_55a938fda82579fd3ec29b3c28" ON "team" ("userId") `);
|
||||||
|
}
|
||||||
|
|
||||||
|
public async down(queryRunner: QueryRunner): Promise<any> {
|
||||||
|
await queryRunner.query(`DROP INDEX "IDX_55a938fda82579fd3ec29b3c28"`);
|
||||||
|
await queryRunner.query(`ALTER TABLE "team" RENAME TO "temporary_team"`);
|
||||||
|
await queryRunner.query(`CREATE TABLE "team" ("id" integer PRIMARY KEY AUTOINCREMENT NOT NULL, "createDate" datetime NOT NULL DEFAULT (datetime('now')), "updateDate" datetime NOT NULL DEFAULT (datetime('now')), "name" varchar NOT NULL, "userId" integer NOT NULL)`);
|
||||||
|
await queryRunner.query(`INSERT INTO "team"("id", "createDate", "updateDate", "name", "userId") SELECT "id", "createDate", "updateDate", "name", "userId" FROM "temporary_team"`);
|
||||||
|
await queryRunner.query(`DROP TABLE "temporary_team"`);
|
||||||
|
await queryRunner.query(`CREATE INDEX "IDX_55a938fda82579fd3ec29b3c28" ON "team" ("userId") `);
|
||||||
|
await queryRunner.query(`ALTER TABLE "vote" RENAME TO "temporary_vote"`);
|
||||||
|
await queryRunner.query(`CREATE TABLE "vote" ("id" integer PRIMARY KEY AUTOINCREMENT NOT NULL, "createDate" datetime NOT NULL DEFAULT (datetime('now')), "updateDate" datetime NOT NULL DEFAULT (datetime('now')), "userId" integer NOT NULL, "commentId" integer NOT NULL, CONSTRAINT "FK_f5de237a438d298031d11a57c3b" FOREIGN KEY ("userId") REFERENCES "user" ("id") ON DELETE NO ACTION ON UPDATE NO ACTION, CONSTRAINT "FK_ad37adcff60fdb9670a97868ab1" FOREIGN KEY ("commentId") REFERENCES "comment" ("id") ON DELETE NO ACTION ON UPDATE NO ACTION)`);
|
||||||
|
await queryRunner.query(`INSERT INTO "vote"("id", "createDate", "updateDate", "userId", "commentId") SELECT "id", "createDate", "updateDate", "userId", "commentId" FROM "temporary_vote"`);
|
||||||
|
await queryRunner.query(`DROP TABLE "temporary_vote"`);
|
||||||
|
await queryRunner.query(`ALTER TABLE "spam" RENAME TO "temporary_spam"`);
|
||||||
|
await queryRunner.query(`CREATE TABLE "spam" ("id" integer PRIMARY KEY AUTOINCREMENT NOT NULL, "createDate" datetime NOT NULL DEFAULT (datetime('now')), "updateDate" datetime NOT NULL DEFAULT (datetime('now')), "userId" integer NOT NULL, "commentId" integer NOT NULL, CONSTRAINT "FK_ec8bc4fa789466cf62f5949f5cc" FOREIGN KEY ("userId") REFERENCES "user" ("id") ON DELETE NO ACTION ON UPDATE NO ACTION, CONSTRAINT "FK_1bf468db8f4d18b424bb3eafae5" FOREIGN KEY ("commentId") REFERENCES "comment" ("id") ON DELETE NO ACTION ON UPDATE NO ACTION)`);
|
||||||
|
await queryRunner.query(`INSERT INTO "spam"("id", "createDate", "updateDate", "userId", "commentId") SELECT "id", "createDate", "updateDate", "userId", "commentId" FROM "temporary_spam"`);
|
||||||
|
await queryRunner.query(`DROP TABLE "temporary_spam"`);
|
||||||
|
await queryRunner.query(`DROP INDEX "IDX_fe13edd1431a248a0eeac11ae4"`);
|
||||||
|
await queryRunner.query(`DROP INDEX "IDX_4a06baede7d9cf51aef879fb0e"`);
|
||||||
|
await queryRunner.query(`DROP INDEX "IDX_e03827c061fbf85fd3aae454ae"`);
|
||||||
|
await queryRunner.query(`DROP INDEX "IDX_55a938fda82579fd3ec29b3c28"`);
|
||||||
|
await queryRunner.query(`DROP INDEX "IDX_28c5d1d16da7908c97c9bc2f74"`);
|
||||||
|
await queryRunner.query(`ALTER TABLE "site" RENAME TO "temporary_site"`);
|
||||||
|
await queryRunner.query(`CREATE TABLE "site" ("id" integer PRIMARY KEY AUTOINCREMENT NOT NULL, "createDate" datetime NOT NULL DEFAULT (datetime('now')), "updateDate" datetime NOT NULL DEFAULT (datetime('now')), "name" varchar NOT NULL, "domain" varchar NOT NULL, "userId" integer NOT NULL, "teamId" integer NOT NULL, CONSTRAINT "FK_4a06baede7d9cf51aef879fb0e4" FOREIGN KEY ("teamId") REFERENCES "team" ("id") ON DELETE NO ACTION ON UPDATE NO ACTION, CONSTRAINT "FK_e03827c061fbf85fd3aae454aec" FOREIGN KEY ("userId") REFERENCES "user" ("id") ON DELETE NO ACTION ON UPDATE NO ACTION)`);
|
||||||
|
await queryRunner.query(`INSERT INTO "site"("id", "createDate", "updateDate", "name", "domain", "userId", "teamId") SELECT "id", "createDate", "updateDate", "name", "domain", "userId", "teamId" FROM "temporary_site"`);
|
||||||
|
await queryRunner.query(`DROP TABLE "temporary_site"`);
|
||||||
|
await queryRunner.query(`ALTER TABLE "team" RENAME TO "temporary_team"`);
|
||||||
|
await queryRunner.query(`CREATE TABLE "team" ("id" integer PRIMARY KEY AUTOINCREMENT NOT NULL, "createDate" datetime NOT NULL DEFAULT (datetime('now')), "updateDate" datetime NOT NULL DEFAULT (datetime('now')))`);
|
||||||
|
await queryRunner.query(`INSERT INTO "team"("id", "createDate", "updateDate") SELECT "id", "createDate", "updateDate" FROM "temporary_team"`);
|
||||||
|
await queryRunner.query(`DROP TABLE "temporary_team"`);
|
||||||
|
await queryRunner.query(`ALTER TABLE "team" RENAME TO "temporary_team"`);
|
||||||
|
await queryRunner.query(`CREATE TABLE "team" ("id" integer PRIMARY KEY AUTOINCREMENT NOT NULL, "createDate" datetime NOT NULL DEFAULT (datetime('now')), "updateDate" datetime NOT NULL DEFAULT (datetime('now')), "url" varchar NOT NULL)`);
|
||||||
|
await queryRunner.query(`INSERT INTO "team"("id", "createDate", "updateDate") SELECT "id", "createDate", "updateDate" FROM "temporary_team"`);
|
||||||
|
await queryRunner.query(`DROP TABLE "temporary_team"`);
|
||||||
|
await queryRunner.query(`ALTER TABLE "site" RENAME TO "temporary_site"`);
|
||||||
|
await queryRunner.query(`CREATE TABLE "site" ("id" integer PRIMARY KEY AUTOINCREMENT NOT NULL, "createDate" datetime NOT NULL DEFAULT (datetime('now')), "updateDate" datetime NOT NULL DEFAULT (datetime('now')), "name" varchar NOT NULL, "domain" varchar NOT NULL, "userId" integer NOT NULL, "teamId" integer NOT NULL, CONSTRAINT "FK_4a06baede7d9cf51aef879fb0e4" FOREIGN KEY ("teamId") REFERENCES "team" ("id") ON DELETE NO ACTION ON UPDATE NO ACTION, CONSTRAINT "FK_e03827c061fbf85fd3aae454aec" FOREIGN KEY ("userId") REFERENCES "user" ("id") ON DELETE NO ACTION ON UPDATE NO ACTION)`);
|
||||||
|
await queryRunner.query(`INSERT INTO "site"("id", "createDate", "updateDate", "name", "domain", "userId", "teamId") SELECT "id", "createDate", "updateDate", "name", "domain", "userId", "teamId" FROM "temporary_site"`);
|
||||||
|
await queryRunner.query(`DROP TABLE "temporary_site"`);
|
||||||
|
await queryRunner.query(`ALTER TABLE "vote" RENAME TO "temporary_vote"`);
|
||||||
|
await queryRunner.query(`CREATE TABLE "vote" ("id" integer PRIMARY KEY AUTOINCREMENT NOT NULL, "createDate" datetime NOT NULL DEFAULT (datetime('now')), "updateDate" datetime NOT NULL DEFAULT (datetime('now')), "userId" integer NOT NULL, "commentId" integer NOT NULL, CONSTRAINT "UQ_5ef3b030c86a67d7c3cce97a978" UNIQUE ("userId", "commentId"), CONSTRAINT "FK_f5de237a438d298031d11a57c3b" FOREIGN KEY ("userId") REFERENCES "user" ("id") ON DELETE NO ACTION ON UPDATE NO ACTION, CONSTRAINT "FK_ad37adcff60fdb9670a97868ab1" FOREIGN KEY ("commentId") REFERENCES "comment" ("id") ON DELETE NO ACTION ON UPDATE NO ACTION)`);
|
||||||
|
await queryRunner.query(`INSERT INTO "vote"("id", "createDate", "updateDate", "userId", "commentId") SELECT "id", "createDate", "updateDate", "userId", "commentId" FROM "temporary_vote"`);
|
||||||
|
await queryRunner.query(`DROP TABLE "temporary_vote"`);
|
||||||
|
await queryRunner.query(`ALTER TABLE "spam" RENAME TO "temporary_spam"`);
|
||||||
|
await queryRunner.query(`CREATE TABLE "spam" ("id" integer PRIMARY KEY AUTOINCREMENT NOT NULL, "createDate" datetime NOT NULL DEFAULT (datetime('now')), "updateDate" datetime NOT NULL DEFAULT (datetime('now')), "userId" integer NOT NULL, "commentId" integer NOT NULL, CONSTRAINT "UQ_885dac94f112af83664ccd06dd9" UNIQUE ("userId", "commentId"), CONSTRAINT "FK_ec8bc4fa789466cf62f5949f5cc" FOREIGN KEY ("userId") REFERENCES "user" ("id") ON DELETE NO ACTION ON UPDATE NO ACTION, CONSTRAINT "FK_1bf468db8f4d18b424bb3eafae5" FOREIGN KEY ("commentId") REFERENCES "comment" ("id") ON DELETE NO ACTION ON UPDATE NO ACTION)`);
|
||||||
|
await queryRunner.query(`INSERT INTO "spam"("id", "createDate", "updateDate", "userId", "commentId") SELECT "id", "createDate", "updateDate", "userId", "commentId" FROM "temporary_spam"`);
|
||||||
|
await queryRunner.query(`DROP TABLE "temporary_spam"`);
|
||||||
|
await queryRunner.query(`CREATE INDEX "IDX_fe13edd1431a248a0eeac11ae4" ON "comment" ("storyId") `);
|
||||||
|
await queryRunner.query(`CREATE INDEX "IDX_28c5d1d16da7908c97c9bc2f74" ON "session" ("expiredAt") `);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@ -33,7 +33,7 @@ export class LoginRoutes extends BaseRoute<IAPIDef> {
|
|||||||
}
|
}
|
||||||
await req.logInPromise(user)
|
await req.logInPromise(user)
|
||||||
res.redirect(req.baseUrl)
|
res.redirect(req.baseUrl)
|
||||||
// TODO return user
|
return user
|
||||||
})
|
})
|
||||||
|
|
||||||
t.get('/auth/logout', async (req, res) => {
|
t.get('/auth/logout', async (req, res) => {
|
||||||
|
|||||||
61
packages/server/src/routes/TeamRoutes.test.ts
Normal file
61
packages/server/src/routes/TeamRoutes.test.ts
Normal file
@ -0,0 +1,61 @@
|
|||||||
|
import {test} from '../test'
|
||||||
|
|
||||||
|
describe('team', () => {
|
||||||
|
|
||||||
|
test.withDatabase()
|
||||||
|
const t = test.request('/api')
|
||||||
|
|
||||||
|
let cookie!: string
|
||||||
|
let token!: string
|
||||||
|
beforeEach(async () => {
|
||||||
|
const session = await test.registerAccount()
|
||||||
|
cookie = session.cookie
|
||||||
|
token = session.token
|
||||||
|
t.setHeaders({ cookie, 'x-csrf-token': token })
|
||||||
|
})
|
||||||
|
|
||||||
|
async function createTeam(name: string) {
|
||||||
|
const response = await t
|
||||||
|
.post('/teams')
|
||||||
|
.send({
|
||||||
|
name: 'test',
|
||||||
|
})
|
||||||
|
.expect(200)
|
||||||
|
expect(response.body.id).toBeTruthy()
|
||||||
|
return response.body
|
||||||
|
}
|
||||||
|
|
||||||
|
describe('POST /teams', () => {
|
||||||
|
it('creates a new team', async () => {
|
||||||
|
const team = await createTeam('test')
|
||||||
|
expect(team.name).toEqual('test')
|
||||||
|
})
|
||||||
|
})
|
||||||
|
|
||||||
|
describe('GET /teams/:id', () => {
|
||||||
|
it('retrieves a team by id', async () => {
|
||||||
|
const team = await createTeam('test')
|
||||||
|
const response = await t
|
||||||
|
.get('/teams/:id', {
|
||||||
|
id: team.id,
|
||||||
|
})
|
||||||
|
.expect(200)
|
||||||
|
expect(response.body).toEqual(team)
|
||||||
|
})
|
||||||
|
})
|
||||||
|
|
||||||
|
describe('GET /my/teams', () => {
|
||||||
|
it('retrieves all teams belonging to current user', async () => {
|
||||||
|
const team = await createTeam('test')
|
||||||
|
const response = await t
|
||||||
|
.get('/my/teams')
|
||||||
|
.expect(200)
|
||||||
|
expect(response.body).toContainEqual(team)
|
||||||
|
})
|
||||||
|
})
|
||||||
|
|
||||||
|
// describe('GET /my/teams', () => {
|
||||||
|
|
||||||
|
// })
|
||||||
|
|
||||||
|
})
|
||||||
@ -1,4 +1,8 @@
|
|||||||
export * from './application'
|
|
||||||
export * from './BaseRoute'
|
export * from './BaseRoute'
|
||||||
|
export * from './CommentRoutes'
|
||||||
export * from './LoginRoutes'
|
export * from './LoginRoutes'
|
||||||
|
export * from './SiteRoutes'
|
||||||
|
export * from './StoryRoutes'
|
||||||
|
export * from './TeamRoutes'
|
||||||
export * from './UserRoutes'
|
export * from './UserRoutes'
|
||||||
|
export * from './application'
|
||||||
|
|||||||
@ -1,2 +1,10 @@
|
|||||||
export * from './UserService'
|
export * from './CommentService'
|
||||||
|
export * from './ICommentService'
|
||||||
|
export * from './ISiteService'
|
||||||
|
export * from './IStoryService'
|
||||||
|
export * from './ITeamService'
|
||||||
export * from './IUserService'
|
export * from './IUserService'
|
||||||
|
export * from './SiteService'
|
||||||
|
export * from './StoryService'
|
||||||
|
export * from './TeamService'
|
||||||
|
export * from './UserService'
|
||||||
|
|||||||
@ -1,5 +1,10 @@
|
|||||||
import supertest from 'supertest'
|
import supertest from 'supertest'
|
||||||
import {IMethod, IRoutes} from '@rondo/common'
|
import {
|
||||||
|
IMethod,
|
||||||
|
IRequestParams,
|
||||||
|
IRoutes,
|
||||||
|
URLFormatter,
|
||||||
|
} from '@rondo/common'
|
||||||
|
|
||||||
// https://stackoverflow.com/questions/48215950/exclude-property-from-type
|
// https://stackoverflow.com/questions/48215950/exclude-property-from-type
|
||||||
type Omit<T, K extends keyof T> = Pick<T, Exclude<keyof T, K>>
|
type Omit<T, K extends keyof T> = Pick<T, Exclude<keyof T, K>>
|
||||||
@ -37,6 +42,7 @@ export interface IHeaders {
|
|||||||
export class RequestTester<R extends IRoutes> {
|
export class RequestTester<R extends IRoutes> {
|
||||||
|
|
||||||
protected headers: IHeaders = {}
|
protected headers: IHeaders = {}
|
||||||
|
protected formatter: URLFormatter = new URLFormatter()
|
||||||
|
|
||||||
constructor(
|
constructor(
|
||||||
readonly app: Express.Application,
|
readonly app: Express.Application,
|
||||||
@ -49,21 +55,22 @@ export class RequestTester<R extends IRoutes> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
request<M extends IMethod, P extends keyof R & string>(
|
request<M extends IMethod, P extends keyof R & string>(
|
||||||
method: M, path: P,
|
method: M, path: P, params?: IRequestParams,
|
||||||
)
|
)
|
||||||
: IRequest<R, P, M> {
|
: IRequest<R, P, M> {
|
||||||
const test = supertest(this.app)[method](`${this.baseUrl}${path}`)
|
const url = this.formatter.format(path, params)
|
||||||
|
const test = supertest(this.app)[method](`${this.baseUrl}${url}`)
|
||||||
Object.keys(this.headers).forEach(key => {
|
Object.keys(this.headers).forEach(key => {
|
||||||
test.set(key, this.headers[key])
|
test.set(key, this.headers[key])
|
||||||
})
|
})
|
||||||
return test
|
return test
|
||||||
}
|
}
|
||||||
|
|
||||||
get<P extends keyof R & string>(path: P) {
|
get<P extends keyof R & string>(path: P, params?: IRequestParams) {
|
||||||
return this.request('get', path)
|
return this.request('get', path, params)
|
||||||
}
|
}
|
||||||
|
|
||||||
post<P extends keyof R & string>(path: P) {
|
post<P extends keyof R & string>(path: P, params?: IRequestParams) {
|
||||||
return this.request('post', path)
|
return this.request('post', path)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -101,6 +101,7 @@ export class TestUtils<T extends IRoutes> {
|
|||||||
return {
|
return {
|
||||||
cookie: response.header['set-cookie'] as string,
|
cookie: response.header['set-cookie'] as string,
|
||||||
userId: response.body.userId,
|
userId: response.body.userId,
|
||||||
|
token,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user