Skip to content

Commit

Permalink
Merge pull request #4 from SardonyxApp/dev-board
Browse files Browse the repository at this point in the history
Implement tasklist features
  • Loading branch information
natsuozawa authored Apr 6, 2019
2 parents 6c0452b + 6582a68 commit 488a107
Show file tree
Hide file tree
Showing 90 changed files with 6,404 additions and 1,160 deletions.
167 changes: 155 additions & 12 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,22 +1,17 @@
# sardonyx-server
サードニクス

Server for Sardonyx・サードニクスのサーバー
Server for Sardonyx

## About・概要
Sardonyx is an online solution to transform how students and teachers use technology at the International Baccalaureate Diploma Program in Tokyo Metropolitan Kokusai High School. Sardonyx offers a cross-platfrom experience for all its users, through its mobile and web platforms. This repository contains code for Sardonyx's mobile application.
## About
Sardonyx is an online solution to transform how high school students and teachers use technology to manage workloads. Sardonyx offers a cross-platfrom experience for all its users, through its mobile and web platforms. This repository contains code for Sardonyx's web application, targeted for computers and tablets.

The mobile application offers a responsive mobile experience of Kokusai's online environment. It also provides a real time messaging service between students and teachers. This is a solution to enhance student-teacher communication while complying to the Tokyo Metropolitan Board of Education's policies.
The web application offers a group tasklist accessible by both teachers and students. Students and teachers benefit from the transparency of the workload, organized by due dates, subjects, and task categories. Each task on the list can be given a detailed description.

サードニクスは東京都立国際高校国際バカロレアコースの生徒と教員のテクノロジーの使い方を改新するためのオンラインソリューションです。
スマートフォンとウェブアプリケーションを通じてサードニクスはクロスプラットフォームなサービスを提供する予定です。このリポジトリでは、サードニクスのスマートフォンアプリケーションのコードを載せております。
## How to Use
Navigate to [sardonyx.app](https://sardonyx.app), then enter your credentials. Students can use their Managebac credentials to login, while teachers are assigned a login and a password.

本アプリケーションはスマートフォンでの国際高校のICT環境を改善するほか、生徒・教員間のリアルタイムメッセージングサービスを提供目標としています。これは東京都教育委員会のポリシーに従いながら、生徒と先生の間のコミュニケーションを改善するソリューションなのです。

## How to Use・使用方法
Sardonyx is currently under development and is not available for use.

サードニクスは現在開発途中で、まだ非公開です。
Read the info page in the app to learn more about using the application.

## API
Sardonyx's Managebac API can be accessed at the following endpoints.
Expand Down Expand Up @@ -347,5 +342,153 @@ Required: `Reflection-Data` header with JSON:
}
```

### Web-based Authentication API
#### Student login
```
POST /login/student
```

Required: multipart form in request body with `login` and `password` for `https://kokusaiib.managebac.com`

#### Teacher login
```
POST /login/teacher
```

Required: multipart form in request body with Sardonyx `login` and `password`

#### Logout
```
GET /logout
```

Required: valid signed JWT cookie

#### Change Password (teachers)
```
POST /password
```

Required: valid signed JWT cookie with email and JSON request body in request body with `new_password`

### Tasklist API
#### Load user details

```
GET /app/user
GET /app/user?tasklist=:tasklist
```

Required: valid signed JWT cookie with `email` property and `tasklist` property or a `tasklist` URL parameter

Tasklists can be specified for retrieving default labels (teachers only)

#### Change default labels
Add default labels
```
POST /app/user/subjects?id=:id
POST /app/user/categories?id=:id
```

Remove default labels
```
DELETE /app/user/subjects?id=:id
DELETE /app/user/categories?id=:id
```

Required: valid signed JWT cookie with `id` property and `id` URL parameter (for label's id)

#### Change default tasklist
```
PATCH /app/user/tasklist?id=:id
```

Required: valid signed JWT cookie with `id` property and `id` URL parameter (for tasklist's id)

#### Load tasklist
```
GET /app/tasklist
GET /app/tasklist?tasklist=:tasklist
GET /app/tasklist?tasklist=all
```

Required for students: valid signed JWT cookie with `tasklist` property

Required for teachers: valid signed JWT cookie with `tasklist` property or a `tasklist` URL parameter

To select all tasklists, pass `all` as the tasklist URL parameter (teachers only)

#### Load tasks
```
GET /app/tasks
GET /app/tasks?tasklist=:tasklist
GET /app/tasks?full=true
```

Required for students: valid signed JWT cookie with `tasklist` property

Required for teachers: valid signed JWT token with `tasklist` property or a `tasklist` URL parameter

To select labels associated with tasks, pass true for `full`.

#### Change tasks
Create tasks
```
POST /app/task
```

Required: valid signed JWT cookie and JSON request body with task information

Edit tasks
```
PATCH /app/task?id=:id
```

Required: valid signed JWT cookie, `id` URL parameter, and JSON request body with task information.

Delete tasks
```
DELETE /app/task?id=:id
```

Required: valid signed JWT cookie and `id` URL parameter.

#### Load subjects or categories labels
```
GET /app/subjects
GET /app/subjects?tasklist=:tasklist
GET /app/categories
GET /app/categories?tasklist=:tasklist
```

Required for students: valid signed JWT cookie with `tasklist` property

Required for teachers: valid signed JWT with `tasklist` property or a `tasklist` URL parameter

#### Change subjects or categories labels
Add labels
```
POST /app/subjects
POST /app/categories
```

Required: valid signed JWT cookie and JSON request body with label information.

Edit labels
```
PATCH /app/subjects?id=:id
PATCH /app/categories?id=:id
```

Required: valid signed JWT cookie, `id` URL paramter, JSON request body with label information

Delete labels
```
DELETE /app/subjects?id=:id
DELETE /app/categories?id=:id
```

Required: valid signed JWT cookie and `id` URL parameter

## Contribution
For contribution, see `CONTRIBUTING.md` in SardonyxApp/sardonyx repository.
13 changes: 0 additions & 13 deletions __tests__/api.test.js
Original file line number Diff line number Diff line change
@@ -1,19 +1,6 @@
const request = require('supertest');
const app = require('../app');

describe('Random API', () => {
describe('GET /random', () => {
test('GET /random should return 401 or 200', (done) => {
request(app)
.get('/random')
.then(response => {
expect(response.statusCode === 200 || response.statusCode === 401).toBeTruthy();
done();
});
});
});
});

describe('CORS', () => {
test('GET /api should have Access-Control-Allow-Origin set to *', (done) => {
request(app)
Expand Down
131 changes: 70 additions & 61 deletions __tests__/authentication.test.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
const request = require('supertest');
const app = require('../app');
const db = require('../db');

require('dotenv').config();

Expand Down Expand Up @@ -118,67 +119,75 @@ describe('Authentication API', () => {
});
});

describe('POST /api/login', () => {
test('POST /api/login should return 401 without credentials', (done) => {
request(app)
.post('/api/login')
.then(response => {
expect(response.statusCode).toBe(401);
done();
});
});

test('POST /api/login should return 200 with valid credentials', (done) => {
request(app)
.post('/api/login')
.set('Content-Type', 'multipart/form-data')
.field('login', process.env.LOGIN)
.field('password', process.env.PASSWORD)
.then(response => {
expect(response.statusCode).toBe(200);
done();
});
});

test('POST /api/login should return 401 with invalid login', (done) => {
request(app)
.post('/api/login')
.set('Content-Type', 'multipart/form-data')
.field('login', '[email protected]')
.field('password', process.env.PASSWORD)
.then(response => {
expect(response.statusCode).toBe(401);
done();
});
});

test('POST /api/login should return 401 with invalid password', (done) => {
request(app)
.post('/api/login')
.set('Content-Type', 'multipart/form-data')
.field('login', process.env.LOGIN)
.field('password', 'foobar')
.then(response => {
expect(response.statusCode).toBe(401);
done();
});
});

test('POST /api/login should return Login-Token with valid credentials', (done) => {
request(app)
.post('/api/login')
.set('Content-Type', 'multipart/form-data')
.field('login', process.env.LOGIN)
.field('password', process.env.PASSWORD)
.then(response => {
const credentials = JSON.parse(response.headers['login-token'] || '{}');
expect(credentials).toHaveProperty('login');
expect(credentials).toHaveProperty('password');
expect(credentials).toHaveProperty('managebacSession');
expect(credentials).toHaveProperty('cfduid');
expect(credentials).toHaveProperty('authenticityToken');
done();
});
db.connect(err => {
if (err) {
console.error(err);
process.exit(1);
}

describe('POST /api/login', () => {
test('POST /api/login should return 401 without credentials', (done) => {
request(app)
.post('/api/login')
.then(response => {
expect(response.statusCode).toBe(401);
done();
});
});

test('POST /api/login should return 200 with valid credentials', (done) => {
request(app)
.post('/api/login')
.set('Content-Type', 'multipart/form-data')
.field('login', process.env.LOGIN)
.field('password', process.env.PASSWORD)
.then(response => {
expect(response.statusCode).toBe(200);
done();
});
});

test('POST /api/login should return 401 with invalid login', (done) => {
request(app)
.post('/api/login')
.set('Content-Type', 'multipart/form-data')
.field('login', '[email protected]')
.field('password', process.env.PASSWORD)
.then(response => {
expect(response.statusCode).toBe(401);
done();
});
});

test('POST /api/login should return 401 with invalid password', (done) => {
request(app)
.post('/api/login')
.set('Content-Type', 'multipart/form-data')
.field('login', process.env.LOGIN)
.field('password', 'foobar')
.then(response => {
expect(response.statusCode).toBe(401);
done();
});
});

test('POST /api/login should return Login-Token with valid credentials', (done) => {
request(app)
.post('/api/login')
.set('Content-Type', 'multipart/form-data')
.field('login', process.env.LOGIN)
.field('password', process.env.PASSWORD)
.then(response => {
const credentials = JSON.parse(response.headers['login-token'] || '{}');
expect(credentials).toHaveProperty('login');
expect(credentials).toHaveProperty('password');
expect(credentials).toHaveProperty('managebacSession');
expect(credentials).toHaveProperty('cfduid');
expect(credentials).toHaveProperty('authenticityToken');
expect(response.headers).toHaveProperty('sardonyx-token');
done();
});
});
});
});
});
Loading

0 comments on commit 488a107

Please sign in to comment.