Skip to content

Commit

Permalink
Merge pull request #6 from Factorialers/develop
Browse files Browse the repository at this point in the history
[ENHANCEMENT] ユーザー認証・認可を実装
  • Loading branch information
dino3616 authored Jul 12, 2022
2 parents 9ced59c + 923ce4d commit 547dad9
Show file tree
Hide file tree
Showing 47 changed files with 1,636 additions and 275 deletions.
2 changes: 2 additions & 0 deletions .eslintrc.json
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,9 @@
},
"ignorePatterns": ["*.config.js"],
"rules": {
"class-methods-use-this": "off",
"no-useless-constructor": "off",
"import/no-unresolved": "off",
"import/extensions": [
"error",
"ignorePackages",
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
name: 'Publish Graph'
name: 'Publish Graph to Current'
on:
pull_request:
branches:
Expand All @@ -19,4 +19,4 @@ jobs:
run: yarn install --frozen-lockfile

- name: Publish Graph
run: yarn apollo:rover
run: yarn apollo:rover:current
22 changes: 22 additions & 0 deletions .github/workflows/publish-graph-to-develop.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
name: 'Publish Graph to Develop'
on:
pull_request:
branches:
- develop

jobs:
publish-graph:
name: Publish Graph
runs-on: ubuntu-latest
env:
APOLLO_KEY: ${{secrets.APOLLO_KEY}}

steps:
- name: Checkout
uses: actions/checkout@v2

- name: Install Dependencies
run: yarn install --frozen-lockfile

- name: Publish Graph
run: yarn apollo:rover:develop
10 changes: 10 additions & 0 deletions .github/workflows/test.yml
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,16 @@ jobs:
runs-on: ubuntu-latest
env:
DATABASE_URL: postgresql://postgres:postgres@localhost:5432/test?schema=public
FIREBASE_API_KEY: ${{secrets.FIREBASE_API_KEY}}
FIREBASE_AUTH_DOMAIN: ${{secrets.FIREBASE_AUTH_DOMAIN}}
FIREBASE_PROJECT_ID: ${{secrets.FIREBASE_PROJECT_ID}}
FIREBASE_STORAGE_BUCKET: ${{secrets.FIREBASE_STORAGE_BUCKET}}
FIREBASE_SENDER_ID: ${{secrets.FIREBASE_SENDER_ID}}
FIREBASE_API_ID: ${{secrets.FIREBASE_API_ID}}
FIREBASE_MEASUREMENT_ID: ${{secrets.FIREBASE_MEASUREMENT_ID}}
FIREBASE_ADMIN_PROJECT_ID: ${{secrets.FIREBASE_ADMIN_PROJECT_ID}}
FIREBASE_ADMIN_PRIVATE_KEY: ${{secrets.FIREBASE_ADMIN_PRIVATE_KEY}}
FIREBASE_ADMIN_CLIENT_EMAIL: ${{secrets.FIREBASE_ADMIN_CLIENT_EMAIL}}
services:
db:
image: postgres
Expand Down
3 changes: 3 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -37,3 +37,6 @@ lerna-debug.log*
!.vscode/launch.json
!.vscode/extensions.json
*.code-workspace

# firebase admin secret keys
programmist-c0b3c-firebase-adminsdk-*.json
8 changes: 5 additions & 3 deletions jest.config.json
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,9 @@
"transform": {
"^.+\\.(t|j)s$": "ts-jest"
},
"collectCoverageFrom": ["**/*.(t|j)s"],
"coverageDirectory": "../coverage",
"testEnvironment": "node"
"collectCoverageFrom": ["./src/**/*.ts"],
"coveragePathIgnorePatterns": ["dist", "node_modules", "./src/libs/prisma/generated"],
"coverageDirectory": "./coverage",
"testEnvironment": "node",
"setupFiles": ["dotenv/config"]
}
11 changes: 7 additions & 4 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -15,16 +15,17 @@
"start": "nest start",
"prod": "node dist/main",
"lint": "eslint ./src/**/*.ts",
"test": "jest",
"test": "jest --silent=false --verbose false",
"test:watch": "jest --watch",
"test:cov": "jest --coverage",
"test:debug": "node --inspect-brk -r tsconfig-paths/register -r ts-node/register node_modules/.bin/jest --runInBand",
"test:e2e": "jest --config ./test/jest-e2e.json",
"test:e2e": "jest --silent=false --verbose false --config ./test/jest-e2e.json",
"prisma:gen": "prisma generate --schema ./src/libs/prisma/schema.prisma",
"prisma:migrate": "prisma migrate dev --schema ./src/libs/prisma/schema.prisma",
"prisma:clear": "prisma db push --accept-data-loss --schema ./src/libs/prisma/schema.prisma",
"prisma:studio": "prisma studio --schema ./src/libs/prisma/schema.prisma",
"apollo:rover": "rover graph publish Programmist-h0lm9@current --schema ./schema.gql"
"apollo:rover:current": "rover graph publish Programmist-h0lm9@current --schema ./schema.gql",
"apollo:rover:develop": "rover graph publish Programmist-h0lm9@develop --schema ./schema.gql"
},
"dependencies": {
"@nestjs/apollo": "^10.0.14",
Expand All @@ -40,6 +41,8 @@
"class-transformer": "^0.5.1",
"class-validator": "^0.13.2",
"express": "^4.18.1",
"firebase": "^9.8.3",
"firebase-admin": "^11.0.0",
"graphql-tag": "^2.12.6",
"jest-mock-extended": "^2.0.6",
"rxjs": "^7.5.5",
Expand All @@ -51,7 +54,7 @@
"@nestjs/cli": "^8.2.6",
"@nestjs/schematics": "^8.0.11",
"@types/jest": "^28.1.1",
"@types/node": "^17.0.42",
"@types/node": "^18.0.0",
"@typescript-eslint/eslint-plugin": "^5.27.1",
"@typescript-eslint/parser": "^5.27.1",
"apollo-server-express": "^3.8.2",
Expand Down
10 changes: 1 addition & 9 deletions schema.gql
Original file line number Diff line number Diff line change
Expand Up @@ -56,8 +56,6 @@ input NestedStringFilter {
type Query {
findUserById(where: UserWhereUniqueInput!): User
findUsers(cursor: UserWhereUniqueInput, distinct: [UserScalarFieldEnum!], orderBy: [UserOrderByWithRelationInput!], skip: Int, take: Int, where: UserWhereInput): [User!]!
getAllUsers: [User!]!
getAuthorizationHeader: String!
}

enum QueryMode {
Expand Down Expand Up @@ -90,35 +88,30 @@ input StringFilter {
}

type User {
avatarURL: String!
createdAt: DateTime!
id: ID!
name: String!
}

input UserCreateInput {
avatarURL: String!
createdAt: DateTime
id: String
id: String!
name: String!
}

input UserOrderByWithRelationInput {
avatarURL: SortOrder
createdAt: SortOrder
id: SortOrder
name: SortOrder
}

enum UserScalarFieldEnum {
avatarURL
createdAt
id
name
}

input UserUpdateInput {
avatarURL: StringFieldUpdateOperationsInput
createdAt: DateTimeFieldUpdateOperationsInput
id: StringFieldUpdateOperationsInput
name: StringFieldUpdateOperationsInput
Expand All @@ -128,7 +121,6 @@ input UserWhereInput {
AND: [UserWhereInput!]
NOT: [UserWhereInput!]
OR: [UserWhereInput!]
avatarURL: StringFilter
createdAt: DateTimeFilter
id: StringFilter
name: StringFilter
Expand Down
3 changes: 2 additions & 1 deletion src/app/app.module.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,10 @@ import { Module } from '@nestjs/common';
import Components from '../components';
import EnvModule from '../config/environment/getter/getter.module';
import GraphQLConfig from '../config/graphql/graphql.config';
import FirebaseModule from '../libs/firebase/firebase.module';
import PrismaModule from '../libs/prisma/prisma.module';

@Module({
imports: [EnvModule, GraphQLConfig, PrismaModule, ...Components],
imports: [EnvModule, GraphQLConfig, PrismaModule, FirebaseModule, ...Components],
})
export default class AppModule {}
54 changes: 54 additions & 0 deletions src/components/user/user.resolver.mutation.spec.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
import FirebaseService from '../../libs/firebase/firebase.service';
import { mock, MockedType } from '../../test/mock';
import UserMutation from './user.resolver.mutation';
import UserService from './user.service';

describe('User Mutation Resolver Test', () => {
let mockedFirebaseService: MockedType<FirebaseService>;
let mockedUserService: MockedType<UserService>;
let userQuery: UserMutation;

beforeEach(() => {
mockedFirebaseService = mock<FirebaseService>();
mockedUserService = mock<UserService>();
userQuery = new UserMutation(mockedFirebaseService, mockedUserService);
});

test('createUser', async () => {
const fakeUser = {
id: 'abc-123',
name: 'yukarisan-lover',
createdAt: new Date(),
};
mockedUserService.create.mockResolvedValue(fakeUser);

const expectUser = fakeUser;
await expect(userQuery.createUser({ data: { id: expectUser.id, name: expectUser.name } })).resolves.toEqual(expectUser);
});

test('updateUser', async () => {
const fakeUser = {
id: 'abc-123',
name: 'yukarisan-lover',
createdAt: new Date(),
};
mockedUserService.update.mockResolvedValue(fakeUser);

const expectUser = fakeUser;
await expect(userQuery.updateUser({ where: { id: expectUser.id }, data: { id: expectUser.id, name: expectUser.name } })).resolves.toEqual(
expectUser,
);
});

test('deleteUser', async () => {
const fakeUser = {
id: 'abc-123',
name: 'yukarisan-lover',
createdAt: new Date(),
};
mockedUserService.delete.mockResolvedValue(fakeUser);

const expectUser = fakeUser;
await expect(userQuery.deleteUser({ where: { id: expectUser.id } })).resolves.toEqual(expectUser);
});
});
22 changes: 18 additions & 4 deletions src/components/user/user.resolver.mutation.ts
Original file line number Diff line number Diff line change
@@ -1,31 +1,45 @@
import { UseGuards } from '@nestjs/common';
import { Resolver, Mutation, Args } from '@nestjs/graphql';
import AuthGuard from '../../guards/auth.guard';
import FirebaseService from '../../libs/firebase/firebase.service';
import { CreateOneUserArgs } from '../../libs/prisma/generated/user/create-one-user/args';
import { DeleteOneUserArgs } from '../../libs/prisma/generated/user/delete-one-user/args';
import { UpdateOneUserArgs } from '../../libs/prisma/generated/user/update-one-user/args';
import { User } from '../../libs/prisma/generated/user/user/model';
import UserService from './user.service';

@Resolver()
@UseGuards(AuthGuard)
export default class UserMutation {
constructor(private service: UserService) {}
constructor(private firebaseService: FirebaseService, private service: UserService) {}

@Mutation(() => User)
async createUser(@Args() args: CreateOneUserArgs) {
const user = this.service.create(args);
const user = await this.service.create(args);

return user;
}

@Mutation(() => User)
async updateUser(@Args() args: UpdateOneUserArgs) {
const user = this.service.update(args);
if (!args.where.id) {
throw new Error('where.idは必須のプロパティです。');
}

const user = await this.service.update(args);
await this.firebaseService.adminAuth.updateUser(args.where.id, { displayName: args.data.name });

return user;
}

@Mutation(() => User)
async deleteUser(@Args() args: DeleteOneUserArgs) {
const user = this.service.delete(args);
if (!args.where.id) {
throw new Error('where.idは必須のプロパティです。');
}

const user = await this.service.delete(args);
await this.firebaseService.adminAuth.deleteUser(args.where.id);

return user;
}
Expand Down
54 changes: 54 additions & 0 deletions src/components/user/user.resolver.query.spec.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
import { mock, MockedType } from '../../test/mock';
import UserQuery from './user.resolver.query';
import UserService from './user.service';

describe('User Query Resolver Test', () => {
let mockedUserService: MockedType<UserService>;
let userQuery: UserQuery;

beforeEach(() => {
mockedUserService = mock<UserService>();
userQuery = new UserQuery(mockedUserService);
});

test('findUserById', async () => {
const fakeUser = {
id: 'abc-123',
name: 'yukarisan-lover',
createdAt: new Date(),
};
mockedUserService.findUser.mockResolvedValue(fakeUser);

const expectUser = fakeUser;
await expect(userQuery.findUserById({ where: { id: expectUser.id } })).resolves.toEqual(expectUser);
});

test('findUsers', async () => {
const fakeUsers = [
{
id: 'abc-123',
name: 'yukarisan-lover',
createdAt: new Date(),
},
{
id: 'abc-124',
name: 'mikusan-lover',
createdAt: new Date(),
},
];
mockedUserService.findUsers.mockResolvedValue(fakeUsers);

const expectUsers = fakeUsers;
await expect(
userQuery.findUsers({
where: {
AND: expectUsers.map((user) => ({
name: {
equals: user.name,
},
})),
},
}),
).resolves.toEqual(expectUsers);
});
});
20 changes: 2 additions & 18 deletions src/components/user/user.resolver.query.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,4 @@
import { UseGuards } from '@nestjs/common';
import { Resolver, Query, Args, Context } from '@nestjs/graphql';
import AuthGuard from '../../guards/auth.guard';
import { Resolver, Query, Args } from '@nestjs/graphql';
import { FindManyUserArgs } from '../../libs/prisma/generated/user/find-many-user/args';
import { FindUniqueUserArgs } from '../../libs/prisma/generated/user/find-unique-user/args';
import { User } from '../../libs/prisma/generated/user/user/model';
Expand All @@ -10,13 +8,6 @@ import UserService from './user.service';
export default class UserQuery {
constructor(private service: UserService) {}

// eslint-disable-next-line class-methods-use-this
@Query(() => String)
@UseGuards(AuthGuard)
getAuthorizationHeader(@Context() context): string {
return context.authorization;
}

@Query(() => User, { nullable: true })
async findUserById(@Args() args: FindUniqueUserArgs): Promise<User | null> {
const user = await this.service.findUser(args);
Expand All @@ -26,14 +17,7 @@ export default class UserQuery {

@Query(() => [User])
async findUsers(@Args() args: FindManyUserArgs): Promise<User[]> {
const users = this.service.findUsers(args);

return users;
}

@Query(() => [User])
async getAllUsers() {
const users = this.service.findUsers();
const users = await this.service.findUsers(args);

return users;
}
Expand Down
Loading

0 comments on commit 547dad9

Please sign in to comment.