Pass subscriptionId when publishing/accessing published notebooks (#288)

We need to record `subscriptionId` when publishing a notebook, also we want to restrict notebooks to only from a particular `subscriptionId` when accessing `My published work` tab. This change passes the `subscriptionId` as part of the URL when publishing or accessing published notebooks.
This commit is contained in:
Tanuj Mittal 2020-10-21 17:01:22 -07:00 committed by GitHub
parent 1e19f02fd7
commit 734df3dd18
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 65 additions and 35 deletions

View File

@ -1,9 +1,12 @@
import ko from "knockout";
import { HttpHeaders, HttpStatusCodes } from "../Common/Constants";
import { IPinnedRepo, JunoClient } from "./JunoClient";
import { IPinnedRepo, JunoClient, IPublishNotebookRequest } from "./JunoClient";
import { configContext } from "../ConfigContext";
import { getAuthorizationHeader } from "../Utils/AuthorizationUtils";
import { DatabaseAccount } from "../Contracts/DataModels";
import { updateUserContext, userContext } from "../UserContext";
const sampleSubscriptionId = "subscriptionId";
const sampleDatabaseAccount: DatabaseAccount = {
id: "id",
@ -131,11 +134,20 @@ describe("GitHub", () => {
describe("Gallery", () => {
const junoClient = new JunoClient(ko.observable<DatabaseAccount>(sampleDatabaseAccount));
const originalSubscriptionId = userContext.subscriptionId;
beforeAll(() => {
updateUserContext({ subscriptionId: sampleSubscriptionId });
});
afterEach(() => {
jest.resetAllMocks();
});
afterAll(() => {
updateUserContext({ subscriptionId: originalSubscriptionId });
});
it("getSampleNotebooks", async () => {
window.fetch = jest.fn().mockReturnValue({
status: HttpStatusCodes.OK,
@ -295,12 +307,15 @@ describe("Gallery", () => {
const authorizationHeader = getAuthorizationHeader();
expect(response.status).toBe(HttpStatusCodes.OK);
expect(window.fetch).toBeCalledWith(`${configContext.JUNO_ENDPOINT}/api/notebooks/gallery/published`, {
headers: {
[authorizationHeader.header]: authorizationHeader.token,
[HttpHeaders.contentType]: "application/json"
expect(window.fetch).toBeCalledWith(
`${configContext.JUNO_ENDPOINT}/api/notebooks/${sampleSubscriptionId}/gallery/published`,
{
headers: {
[authorizationHeader.header]: authorizationHeader.token,
[HttpHeaders.contentType]: "application/json"
}
}
});
);
});
it("deleteNotebook", async () => {
@ -330,17 +345,26 @@ describe("Gallery", () => {
const author = "author";
const thumbnailUrl = "thumbnailUrl";
const content = `{ "key": "value" }`;
const addLinkToNotebookViewer = false;
window.fetch = jest.fn().mockReturnValue({
status: HttpStatusCodes.OK,
json: () => undefined as any
});
const response = await junoClient.publishNotebook(name, description, tags, author, thumbnailUrl, content, false);
const response = await junoClient.publishNotebook(
name,
description,
tags,
author,
thumbnailUrl,
content,
addLinkToNotebookViewer
);
const authorizationHeader = getAuthorizationHeader();
expect(response.status).toBe(HttpStatusCodes.OK);
expect(window.fetch).toBeCalledWith(
`${configContext.JUNO_ENDPOINT}/api/notebooks/${sampleDatabaseAccount.name}/gallery`,
`${configContext.JUNO_ENDPOINT}/api/notebooks/${sampleSubscriptionId}/${sampleDatabaseAccount.name}/gallery`,
{
method: "PUT",
headers: {
@ -353,8 +377,9 @@ describe("Gallery", () => {
tags,
author,
thumbnailUrl,
content: JSON.parse(content)
})
content: JSON.parse(content),
addLinkToNotebookViewer
} as IPublishNotebookRequest)
}
);
});

View File

@ -5,6 +5,7 @@ import * as DataModels from "../Contracts/DataModels";
import { AuthorizeAccessComponent } from "../Explorer/Controls/GitHub/AuthorizeAccessComponent";
import { IGitHubResponse } from "../GitHub/GitHubClient";
import { IGitHubOAuthToken } from "../GitHub/GitHubOAuthService";
import { userContext } from "../UserContext";
import { getAuthorizationHeader } from "../Utils/AuthorizationUtils";
export interface IJunoResponse<T> {
@ -55,13 +56,15 @@ export interface IUserGallery {
published: string[];
}
interface IPublishNotebookRequest {
// Only exported for unit test
export interface IPublishNotebookRequest {
name: string;
description: string;
tags: string[];
author: string;
thumbnailUrl: string;
content: any;
addLinkToNotebookViewer: boolean;
}
export class JunoClient {
@ -331,7 +334,7 @@ export class JunoClient {
}
public async getPublishedNotebooks(): Promise<IJunoResponse<IGalleryItem[]>> {
return await this.getNotebooks(`${this.getNotebooksUrl()}/gallery/published`, {
return await this.getNotebooks(`${this.getNotebooksUrl()}/${this.getSubscriptionId()}/gallery/published`, {
headers: JunoClient.getHeaders()
});
}
@ -362,28 +365,22 @@ export class JunoClient {
content: string,
isLinkInjectionEnabled: boolean
): Promise<IJunoResponse<IGalleryItem>> {
const response = await window.fetch(`${this.getNotebooksAccountUrl()}/gallery`, {
method: "PUT",
headers: JunoClient.getHeaders(),
body: isLinkInjectionEnabled
? JSON.stringify({
name,
description,
tags,
author,
thumbnailUrl,
content: JSON.parse(content),
addLinkToNotebookViewer: isLinkInjectionEnabled
} as IPublishNotebookRequest)
: JSON.stringify({
name,
description,
tags,
author,
thumbnailUrl,
content: JSON.parse(content)
} as IPublishNotebookRequest)
});
const response = await window.fetch(
`${this.getNotebooksUrl()}/${this.getSubscriptionId()}/${this.getAccount()}/gallery`,
{
method: "PUT",
headers: JunoClient.getHeaders(),
body: JSON.stringify({
name,
description,
tags,
author,
thumbnailUrl,
content: JSON.parse(content),
addLinkToNotebookViewer: isLinkInjectionEnabled
} as IPublishNotebookRequest)
}
);
let data: IGalleryItem;
if (response.status === HttpStatusCodes.OK) {
@ -448,8 +445,16 @@ export class JunoClient {
return `${configContext.JUNO_ENDPOINT}/api/notebooks`;
}
private getAccount(): string {
return this.databaseAccount().name;
}
private getSubscriptionId(): string {
return userContext.subscriptionId;
}
private getNotebooksAccountUrl(): string {
return `${configContext.JUNO_ENDPOINT}/api/notebooks/${this.databaseAccount().name}`;
return `${this.getNotebooksUrl()}/${this.getAccount()}`;
}
private static getHeaders(): HeadersInit {