Skip to content

Commit 83b8a78

Browse files
authored
Implemented the deleteRuleset() API (#609)
* Added deleteRuleset API * Merged with source
1 parent 471aa49 commit 83b8a78

File tree

4 files changed

+118
-0
lines changed

4 files changed

+118
-0
lines changed

src/security-rules/security-rules-api-client.ts

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -103,6 +103,20 @@ export class SecurityRulesApiClient {
103103
return this.sendRequest<RulesetResponse>(request);
104104
}
105105

106+
public deleteRuleset(name: string): Promise<void> {
107+
return Promise.resolve()
108+
.then(() => {
109+
return this.getRulesetName(name);
110+
})
111+
.then((rulesetName) => {
112+
const request: HttpRequestConfig = {
113+
method: 'DELETE',
114+
url: `${this.url}/${rulesetName}`,
115+
};
116+
return this.sendRequest<void>(request);
117+
});
118+
}
119+
106120
public getRelease(name: string): Promise<Release> {
107121
return this.getResource<Release>(`releases/${name}`);
108122
}

src/security-rules/security-rules.ts

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -164,6 +164,18 @@ export class SecurityRules implements FirebaseServiceInterface {
164164
});
165165
}
166166

167+
/**
168+
* Deletes the Ruleset identified by the given name. The input name should be the short name string without
169+
* the project ID prefix. For example, to delete the `projects/project-id/rulesets/my-ruleset`, pass the
170+
* short name "my-ruleset". Rejects with a `not-found` error if the specified Ruleset cannot be found.
171+
*
172+
* @param {string} name Name of the Ruleset to delete.
173+
* @returns {Promise<Ruleset>} A promise that fulfills when the Ruleset is deleted.
174+
*/
175+
public deleteRuleset(name: string): Promise<void> {
176+
return this.client.deleteRuleset(name);
177+
}
178+
167179
private getRulesetForRelease(releaseName: string): Promise<Ruleset> {
168180
return this.client.getRelease(releaseName)
169181
.then((release) => {

test/unit/security-rules/security-rules-api-client.spec.ts

Lines changed: 72 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -304,4 +304,76 @@ describe('SecurityRulesApiClient', () => {
304304
.should.eventually.be.rejected.and.deep.equal(expected);
305305
});
306306
});
307+
308+
describe('deleteRuleset', () => {
309+
const INVALID_NAMES: any[] = [null, undefined, '', 1, true, {}, []];
310+
INVALID_NAMES.forEach((invalidName) => {
311+
it(`should reject when called with: ${JSON.stringify(invalidName)}`, () => {
312+
return apiClient.deleteRuleset(invalidName)
313+
.should.eventually.be.rejected.and.have.property(
314+
'message', 'Ruleset name must be a non-empty string.');
315+
});
316+
});
317+
318+
it(`should reject when called with prefixed name`, () => {
319+
return apiClient.deleteRuleset('projects/foo/rulesets/bar')
320+
.should.eventually.be.rejected.and.have.property(
321+
'message', 'Ruleset name must not contain any "/" characters.');
322+
});
323+
324+
it('should resolve on success', () => {
325+
const stub = sinon
326+
.stub(HttpClient.prototype, 'send')
327+
.resolves(utils.responseFrom({}));
328+
stubs.push(stub);
329+
return apiClient.deleteRuleset(RULESET_NAME)
330+
.then(() => {
331+
expect(stub).to.have.been.calledOnce.and.calledWith({
332+
method: 'DELETE',
333+
url: 'https://firebaserules.googleapis.com/v1/projects/test-project/rulesets/ruleset-id',
334+
});
335+
});
336+
});
337+
338+
it('should throw when a full platform error response is received', () => {
339+
const stub = sinon
340+
.stub(HttpClient.prototype, 'send')
341+
.rejects(utils.errorFrom(ERROR_RESPONSE, 404));
342+
stubs.push(stub);
343+
const expected = new FirebaseSecurityRulesError('not-found', 'Requested entity not found');
344+
return apiClient.deleteRuleset(RULESET_NAME)
345+
.should.eventually.be.rejected.and.deep.equal(expected);
346+
});
347+
348+
it('should throw unknown-error when error code is not present', () => {
349+
const stub = sinon
350+
.stub(HttpClient.prototype, 'send')
351+
.rejects(utils.errorFrom({}, 404));
352+
stubs.push(stub);
353+
const expected = new FirebaseSecurityRulesError('unknown-error', 'Unknown server error: {}');
354+
return apiClient.deleteRuleset(RULESET_NAME)
355+
.should.eventually.be.rejected.and.deep.equal(expected);
356+
});
357+
358+
it('should throw unknown-error for non-json response', () => {
359+
const stub = sinon
360+
.stub(HttpClient.prototype, 'send')
361+
.rejects(utils.errorFrom('not json', 404));
362+
stubs.push(stub);
363+
const expected = new FirebaseSecurityRulesError(
364+
'unknown-error', 'Unexpected response with status: 404 and body: not json');
365+
return apiClient.deleteRuleset(RULESET_NAME)
366+
.should.eventually.be.rejected.and.deep.equal(expected);
367+
});
368+
369+
it('should throw when rejected with a FirebaseAppError', () => {
370+
const expected = new FirebaseAppError('network-error', 'socket hang up');
371+
const stub = sinon
372+
.stub(HttpClient.prototype, 'send')
373+
.rejects(expected);
374+
stubs.push(stub);
375+
return apiClient.deleteRuleset(RULESET_NAME)
376+
.should.eventually.be.rejected.and.deep.equal(expected);
377+
});
378+
});
307379
});

test/unit/security-rules/security-rules.spec.ts

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -342,4 +342,24 @@ describe('SecurityRules', () => {
342342
});
343343
});
344344
});
345+
346+
describe('deleteRuleset', () => {
347+
it('should propagate API errors', () => {
348+
const stub = sinon
349+
.stub(SecurityRulesApiClient.prototype, 'deleteRuleset')
350+
.rejects(EXPECTED_ERROR);
351+
stubs.push(stub);
352+
return securityRules.deleteRuleset('foo')
353+
.should.eventually.be.rejected.and.deep.equal(EXPECTED_ERROR);
354+
});
355+
356+
it('should resolve on success', () => {
357+
const stub = sinon
358+
.stub(SecurityRulesApiClient.prototype, 'deleteRuleset')
359+
.resolves({});
360+
stubs.push(stub);
361+
362+
return securityRules.deleteRuleset('foo');
363+
});
364+
});
345365
});

0 commit comments

Comments
 (0)