Skip to content
This repository has been archived by the owner on Nov 29, 2021. It is now read-only.

Commit

Permalink
feat: finish e2e test of Announcement module
Browse files Browse the repository at this point in the history
  • Loading branch information
YanceyOfficial committed Dec 26, 2019
1 parent 0f5ab25 commit 2af1fd9
Show file tree
Hide file tree
Showing 5 changed files with 223 additions and 126 deletions.
134 changes: 11 additions & 123 deletions schema.gql
Original file line number Diff line number Diff line change
Expand Up @@ -3,13 +3,9 @@
# !!! DO NOT MODIFY THIS FILE BY YOURSELF !!!
# -----------------------------------------------

input AnnouncementInput {
announcement: String!
}

type AnnouncementsModel {
_id: String!
announcement: String!
content: String!
createdAt: String!
updatedAt: String!
}
Expand All @@ -20,131 +16,23 @@ type BatchDeleteModel {
deletedCount: Float
}

input CreateOpenSourceInput {
title: String!
description: String!
url: String!
posterUrl: String!
input CreateAnnouncementInput {
content: String!
}

type Mutation {
createAnnouncement(input: AnnouncementInput!): AnnouncementsModel!
updateAnnouncement(announcement: String!, id: ID!): AnnouncementsModel!
deleteAnnouncement(id: ID!): AnnouncementsModel!
deleteAnnouncements(ids: [ID!]!): AnnouncementsModel!
sendSMS(input: SendSMSInput!): SendSMSRes!
validateSMS(input: ValidateSMSInput!): ValidateSMSRes!
createOpenSource(input: CreateOpenSourceInput!): OpenSourceModel!
updateOpenSourceById(input: UpdateOpenSourceInput!): OpenSourceModel!
deleteOpenSourceById(id: ID!): OpenSourceModel!
deleteOpenSources(ids: [ID!]!): BatchDeleteModel!
}

type OpenSourceModel {
_id: ID!
title: String!
description: String!
url: String!
posterUrl: String!
createdAt: String!
updatedAt: String!
createAnnouncement(input: CreateAnnouncementInput!): AnnouncementsModel!
updateAnnouncementById(input: UpdateAnnouncementInput!): AnnouncementsModel!
deleteAnnouncementById(id: ID!): AnnouncementsModel!
deleteAnnouncements(ids: [ID!]!): BatchDeleteModel!
}

type Query {
announcements: [AnnouncementsModel!]!
announcement(id: ID!): AnnouncementsModel!
getAllSMS: [SMSModel!]!
getOpenSources: [OpenSourceModel!]!
getOpenSourceById(id: ID!): OpenSourceModel!
getBanwagonServiceInfo: ServiceInfoModel!
getBanwagonUsageStats: [UsageStatesModel!]!
}

input SendSMSInput {
phoneNumber: String!
}

type SendSMSRes {
verificationCode: String!
}

type ServiceInfoModel {
vm_type: String!
ve_status: String!
ve_mac1: String!
ve_used_disk_space_b: String!
is_cpu_throttled: String!
ssh_port: Float!
live_hostname: String!
load_average: String!
mem_available_kb: Float!
swap_total_kb: Float!
swap_available_kb: Float!
hostname: String!
node_ip: String!
node_alias: String!
node_location: String!
node_location_id: String!
node_datacenter: String!
location_ipv6_ready: Boolean!
plan: String!
plan_monthly_data: Float!
monthly_data_multiplier: Float!
plan_disk: Float!
plan_ram: Float!
plan_swap: Float!
plan_max_ipv6s: Float!
os: String!
email: String!
data_counter: Float!
data_next_reset: Float!
ip_addresses: [String!]!
private_ip_addresses: [String!]!
ip_nullroutes: [String!]!
iso1: String
iso2: String
available_isos: [String!]!
plan_private_network_available: Boolean!
location_private_network_available: Boolean!
rdns_api_available: Boolean!
ptr: String!
suspended: Boolean!
policy_violation: Boolean!
suspension_count: Float
max_abuse_points: Float!
error: Float!
veid: Float!
getAnnouncements: [AnnouncementsModel!]!
getAnnouncementById(id: ID!): AnnouncementsModel!
}

type SMSModel {
_id: String!
phoneNumber: String!
verificationCode: String!
createdAt: String!
updatedAt: String!
}

input UpdateOpenSourceInput {
title: String!
description: String!
url: String!
posterUrl: String!
input UpdateAnnouncementInput {
id: String!
}

type UsageStatesModel {
timestamp: String!
network_in_bytes: String!
network_out_bytes: String!
disk_read_bytes: String!
cpu_usage: String!
}

input ValidateSMSInput {
phoneNumber: String!
verificationCode: String!
}

type ValidateSMSRes {
success: Boolean!
content: String!
}
2 changes: 1 addition & 1 deletion src/announcements/interfaces/announcement.interface.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import { Document } from 'mongoose'

export interface Announcement extends Document {
readonly _id: string
readonly announcement: string
readonly content: string
readonly createdAt: string
readonly updatedAt: string
}
2 changes: 1 addition & 1 deletion src/announcements/models/announcements.model.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ export class AnnouncementsModel {
public _id: string

@Field({ nullable: false })
public announcement: string
public content: string

@Field({ nullable: false })
public createdAt: string
Expand Down
2 changes: 1 addition & 1 deletion src/announcements/schemas/announcements.schema.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ export const AnnouncementSchema = new mongoose.Schema(
type: String,
default: v4,
},
announcement: {
content: {
type: String,
required: true,
},
Expand Down
209 changes: 209 additions & 0 deletions test/announcements.e2e-spec.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,209 @@
import { NestApplication } from '@nestjs/core'
import { Test, TestingModule } from '@nestjs/testing'
import { MongooseModule } from '@nestjs/mongoose'
import { GraphQLModule } from '@nestjs/graphql'
import request from 'supertest'
import { SCHEMA_GQL_FILE_NAME } from '../src/shared/constants'
import { ConfigModule } from '../src/config/config.module'
import { ConfigService } from '../src/config/config.service'
import { AnnouncementsModule } from '../src/announcements/announcements.module'
import { AnnouncementsModel } from '../src/announcements/models/announcements.model'
import { CreateAnnouncementInput } from '../src/announcements/dtos/create-announcement.input'
import { UpdateAnnouncementInput } from '../src/announcements/dtos/update-announcement.input'
import { BatchDelete } from '../src/database/interfaces/batchDelete.interface'

describe('AnnouncementsController (e2e)', () => {
let app: NestApplication
beforeAll(async () => {
const moduleFixture: TestingModule = await Test.createTestingModule({
imports: [
ConfigModule,
AnnouncementsModule,
MongooseModule.forRootAsync({
useFactory: async (configService: ConfigService) => ({
uri: configService.getMongoURI(),
useFindAndModify: false,
useUnifiedTopology: true,
useNewUrlParser: true,
useCreateIndex: true,
}),
inject: [ConfigService],
}),
GraphQLModule.forRoot({
autoSchemaFile: SCHEMA_GQL_FILE_NAME,
}),
],
}).compile()
app = moduleFixture.createNestApplication()
await app.init()
})

afterAll(async () => {
await app.close()
})

const createdData: CreateAnnouncementInput = {
content: 'blog-be-next',
}

let id = ''

const updatedData: UpdateAnnouncementInput = {
id,
content: 'blog-be-cms',
}

const createDataString = JSON.stringify(createdData).replace(/"([^(")"]+)":/g, '$1:')

// CREATE_ONE
it('createAnnouncement', async () => {
const createOneTypeDefs = `
mutation CreateAnnouncement {
createAnnouncement(input: ${createDataString}) {
_id
content
}
}`

return request(app.getHttpServer())
.post('/graphql')
.send({
operationName: null,
query: createOneTypeDefs,
})
.expect(({ body }) => {
const testData: AnnouncementsModel = body.data.createAnnouncement
id = testData._id
expect(testData.content).toBe(createdData.content)
})
.expect(200)
})

// READ_ALL
it('getAnnouncements', async () => {
const getAllTypeDefs = `
query GetAnnouncements {
getAnnouncements {
_id
content
}
}`

return request(app.getHttpServer())
.post('/graphql')
.send({
operationName: null,
query: getAllTypeDefs,
})
.expect(({ body }) => {
const testData: AnnouncementsModel[] = body.data.getAnnouncements

const firstData = testData[0]

expect(testData.length).toBeGreaterThan(0)
expect(firstData._id).toBe(id)
expect(firstData.content).toBe(createdData.content)
})
.expect(200)
})

// READ_ONE
it('getAnnouncementById', async () => {
const getOneByIdTypeDefs = `
query GetAnnouncementById {
getAnnouncementById(id: "${id}") {
_id
content
}
}`

return request(app.getHttpServer())
.post('/graphql')
.send({
operationName: null,
query: getOneByIdTypeDefs,
})
.expect(({ body }) => {
const testData: AnnouncementsModel = body.data.getAnnouncementById

expect(testData._id).toBe(id)
expect(testData.content).toBe(createdData.content)
})
.expect(200)
})

// UPDATE_ONE
it('updateAnnouncementById', async () => {
const updateDataString = JSON.stringify({ ...updatedData, id }).replace(/"([^(")"]+)":/g, '$1:')

const updateOneByIdTypeDefs = `
mutation UpdateAnnouncementById {
updateAnnouncementById(input: ${updateDataString}) {
_id
content
}
}`

return request(app.getHttpServer())
.post('/graphql')
.send({
operationName: null,
query: updateOneByIdTypeDefs,
})
.expect(({ body }) => {
const testData: AnnouncementsModel = body.data.updateAnnouncementById
expect(testData.content).toBe(updatedData.content)
})
.expect(200)
})

// DELETE_ONE
it('deleteAnnouncementById', async () => {
const deleteOneByIdTypeDefs = `
mutation DeleteAnnouncementById {
deleteAnnouncementById(id: "${id}") {
_id
content
}
}`

return request(app.getHttpServer())
.post('/graphql')
.send({
operationName: null,
query: deleteOneByIdTypeDefs,
})
.expect(({ body }) => {
const testData: AnnouncementsModel = body.data.deleteAnnouncementById

expect(testData.content).toBe(updatedData.content)
})
.expect(200)
})

// BATCH_DELETE
it('deleteAnnouncements', async () => {
const batchDeleteTypeDefs = `
mutation DeleteAnnouncements {
deleteAnnouncements(ids: ["${id}"]) {
ok
n
deletedCount
}
}`

return request(app.getHttpServer())
.post('/graphql')
.send({
operationName: null,
query: batchDeleteTypeDefs,
})
.expect(({ body }) => {
const testData: BatchDelete = body.data.deleteAnnouncements
expect(testData.ok).toBe(1)
expect(testData.n).toBe(0)
expect(testData.deletedCount).toBe(0)
})
.expect(200)
})
})

0 comments on commit 2af1fd9

Please sign in to comment.