Skip to content

Commit

Permalink
feat(rest-crud): implement "updateById" operation
Browse files Browse the repository at this point in the history
Signed-off-by: Miroslav Bajtoš <[email protected]>
  • Loading branch information
bajtos committed Aug 22, 2019
1 parent 323c277 commit c24b1cd
Show file tree
Hide file tree
Showing 2 changed files with 59 additions and 8 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,9 @@ describe('CrudRestController for a simple Product model', () => {
let pen: Product;
let pencil: Product;

const PATCH_DATA = {description: 'patched'};
Object.freeze(PATCH_DATA);

before(setupTestScenario);
after(stopTheApp);
beforeEach(cleanDatabase);
Expand Down Expand Up @@ -144,41 +147,72 @@ describe('CrudRestController for a simple Product model', () => {
});

describe('updateAll', () => {
const patch = {description: 'patched'};
Object.freeze(patch);

beforeEach(seedData);

it('updates all products when no filter was provided', async () => {
const {body} = await client
.patch('/products')
.send(patch)
.send(PATCH_DATA)
.expect(200);
expect(body).to.deepEqual({count: 2});

const stored = await repo.find();
expect(toJSON(stored)).to.deepEqual([
{...toJSON(pen), ...patch},
{...toJSON(pencil), ...patch},
{...toJSON(pen), ...PATCH_DATA},
{...toJSON(pencil), ...PATCH_DATA},
]);
});

it('supports `where` query param', async () => {
const {body} = await client
.patch('/products')
.query({'where[name]': pen.name})
.send(patch)
.send(PATCH_DATA)
.expect(200);
expect(body).to.deepEqual({count: 1});

const stored = await repo.find();
expect(toJSON(stored)).to.deepEqual([
{...toJSON(pen), ...patch},
{...toJSON(pen), ...PATCH_DATA},
{...toJSON(pencil) /* pencil was not patched */},
]);
});
});

describe('updateById', () => {
beforeEach(seedData);

it('updates model with the given id', async () => {
await client
.patch(`/products/${pen.id}`)
.send(PATCH_DATA)
.expect(204);

const stored = await repo.find();
expect(toJSON(stored)).to.deepEqual([
{...toJSON(pen), ...PATCH_DATA},
{...toJSON(pencil) /* pencil was not patched */},
]);
});

// TODO(bajtos) to fully verify this functionality, we should create
// a new test suite that will configure a PK with a different name
// and type, e.g. `pk: string` instead of `id: number`.
it('uses correct schema for the id parameter', async () => {
const spec = app.restServer.getApiSpec();
const findByIdOp = spec.paths['/products/{id}'].patch;
expect(findByIdOp).to.containDeep({
parameters: [
{
name: 'id',
in: 'path',
schema: {type: 'number'},
},
],
});
});
});

async function setupTestScenario() {
const db = new juggler.DataSource({connector: 'memory'});
repo = new DefaultCrudRepository<Product, typeof Product.prototype.id>(
Expand Down
17 changes: 17 additions & 0 deletions packages/rest-crud/src/crud-rest.controller.ts
Original file line number Diff line number Diff line change
Expand Up @@ -212,6 +212,23 @@ export function defineCrudRestController<
where,
);
}

@patch('/{id}', {
responses: {
'204': {description: `${modelName} was updated`},
},
})
async updateById(
@param(idPathParam) id: IdType,
@body(modelCtor, {partial: true}) data: Partial<T>,
): Promise<void> {
await this.repository.updateById(
id,
// FIXME(bajtos) Improve repository API to support this use case
// with no explicit type-casts required
data as DataObject<T>,
);
}
}

// See https://github.com/microsoft/TypeScript/issues/14607
Expand Down

0 comments on commit c24b1cd

Please sign in to comment.