mirror of
				https://github.com/gristlabs/grist-core.git
				synced 2025-06-13 20:53:59 +00:00 
			
		
		
		
	move getTemplateOrg method; enable template org in docker tests (#602)
* move getTemplateOrg method; enable template org in docker tests This moves the `getTemplateOrg` method to a neutral venue for the convenience of `grist-static`, otherwise a lot of awkward dependencies get pulled in needlessly in new parts of the app. This also fixes docker tests using the template org.
This commit is contained in:
		
							parent
							
								
									e1df6039c2
								
							
						
					
					
						commit
						61f954ff05
					
				@ -11,10 +11,10 @@ import {getAuthorizedUserId, getUserId, getUserProfiles, RequestWithLogin} from
 | 
			
		||||
import {getSessionUser, linkOrgWithEmail} from 'app/server/lib/BrowserSession';
 | 
			
		||||
import {expressWrap} from 'app/server/lib/expressWrap';
 | 
			
		||||
import {RequestWithOrg} from 'app/server/lib/extractOrg';
 | 
			
		||||
import {getTemplateOrg} from 'app/server/lib/gristSettings';
 | 
			
		||||
import log from 'app/server/lib/log';
 | 
			
		||||
import {addPermit, clearSessionCacheIfNeeded, getDocScope, getScope, integerParam,
 | 
			
		||||
        isParameterOn, optStringParam, sendOkReply, sendReply, stringParam} from 'app/server/lib/requestUtils';
 | 
			
		||||
import {getTemplateOrg} from 'app/server/lib/sendAppPage';
 | 
			
		||||
import {IWidgetRepository} from 'app/server/lib/WidgetRepository';
 | 
			
		||||
 | 
			
		||||
import {User} from './entity/User';
 | 
			
		||||
 | 
			
		||||
@ -89,6 +89,7 @@ import {Authorizer} from 'app/server/lib/Authorizer';
 | 
			
		||||
import {checksumFile} from 'app/server/lib/checksumFile';
 | 
			
		||||
import {Client} from 'app/server/lib/Client';
 | 
			
		||||
import {DEFAULT_CACHE_TTL, DocManager} from 'app/server/lib/DocManager';
 | 
			
		||||
import {getTemplateOrg} from 'app/server/lib/gristSettings';
 | 
			
		||||
import {ICreateActiveDocOptions} from 'app/server/lib/ICreate';
 | 
			
		||||
import {makeForkIds} from 'app/server/lib/idUtils';
 | 
			
		||||
import {GRIST_DOC_SQL, GRIST_DOC_WITH_TABLE1_SQL} from 'app/server/lib/initialDocSql';
 | 
			
		||||
@ -97,7 +98,6 @@ import log from 'app/server/lib/log';
 | 
			
		||||
import {LogMethods} from "app/server/lib/LogMethods";
 | 
			
		||||
import {NullSandbox, UnavailableSandboxMethodError} from 'app/server/lib/NullSandbox';
 | 
			
		||||
import {DocRequests} from 'app/server/lib/Requests';
 | 
			
		||||
import {getTemplateOrg} from 'app/server/lib/sendAppPage';
 | 
			
		||||
import {shortDesc} from 'app/server/lib/shortDesc';
 | 
			
		||||
import {TableMetadataLoader} from 'app/server/lib/TableMetadataLoader';
 | 
			
		||||
import {DocTriggers} from "app/server/lib/Triggers";
 | 
			
		||||
 | 
			
		||||
@ -20,10 +20,11 @@ import {DocStatus, IDocWorkerMap} from 'app/server/lib/DocWorkerMap';
 | 
			
		||||
import {expressWrap} from 'app/server/lib/expressWrap';
 | 
			
		||||
import {DocTemplate, GristServer} from 'app/server/lib/GristServer';
 | 
			
		||||
import {getCookieDomain} from 'app/server/lib/gristSessions';
 | 
			
		||||
import {getTemplateOrg} from 'app/server/lib/gristSettings';
 | 
			
		||||
import {getAssignmentId} from 'app/server/lib/idUtils';
 | 
			
		||||
import log from 'app/server/lib/log';
 | 
			
		||||
import {adaptServerUrl, addOrgToPathIfNeeded, pruneAPIResult, trustOrigin} from 'app/server/lib/requestUtils';
 | 
			
		||||
import {getTemplateOrg, ISendAppPageOptions} from 'app/server/lib/sendAppPage';
 | 
			
		||||
import {ISendAppPageOptions} from 'app/server/lib/sendAppPage';
 | 
			
		||||
 | 
			
		||||
export interface AttachOptions {
 | 
			
		||||
  app: express.Application;                // Express app to which to add endpoints
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										13
									
								
								app/server/lib/gristSettings.ts
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										13
									
								
								app/server/lib/gristSettings.ts
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,13 @@
 | 
			
		||||
import {appSettings} from 'app/server/lib/AppSettings';
 | 
			
		||||
 | 
			
		||||
export function getTemplateOrg() {
 | 
			
		||||
  let org = appSettings.section('templates').flag('org').readString({
 | 
			
		||||
    envVar: 'GRIST_TEMPLATE_ORG',
 | 
			
		||||
  });
 | 
			
		||||
  if (!org) { return null; }
 | 
			
		||||
 | 
			
		||||
  if (process.env.GRIST_ID_PREFIX) {
 | 
			
		||||
    org += `-${process.env.GRIST_ID_PREFIX}`;
 | 
			
		||||
  }
 | 
			
		||||
  return org;
 | 
			
		||||
}
 | 
			
		||||
@ -3,10 +3,10 @@ import {isAffirmative} from 'app/common/gutil';
 | 
			
		||||
import {getTagManagerSnippet} from 'app/common/tagManager';
 | 
			
		||||
import {Document} from 'app/common/UserAPI';
 | 
			
		||||
import {SUPPORT_EMAIL} from 'app/gen-server/lib/HomeDBManager';
 | 
			
		||||
import {appSettings} from 'app/server/lib/AppSettings';
 | 
			
		||||
import {isAnonymousUser, isSingleUserMode, RequestWithLogin} from 'app/server/lib/Authorizer';
 | 
			
		||||
import {RequestWithOrg} from 'app/server/lib/extractOrg';
 | 
			
		||||
import {GristServer} from 'app/server/lib/GristServer';
 | 
			
		||||
import {getTemplateOrg} from 'app/server/lib/gristSettings';
 | 
			
		||||
import {getSupportedEngineChoices} from 'app/server/lib/serverUtils';
 | 
			
		||||
import {readLoadedLngs, readLoadedNamespaces} from 'app/server/localization';
 | 
			
		||||
import * as express from 'express';
 | 
			
		||||
@ -154,18 +154,6 @@ export function makeSendAppPage(opts: {
 | 
			
		||||
  };
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
export function getTemplateOrg() {
 | 
			
		||||
  let org = appSettings.section('templates').flag('org').readString({
 | 
			
		||||
    envVar: 'GRIST_TEMPLATE_ORG',
 | 
			
		||||
  });
 | 
			
		||||
  if (!org) { return null; }
 | 
			
		||||
 | 
			
		||||
  if (process.env.GRIST_ID_PREFIX) {
 | 
			
		||||
    org += `-${process.env.GRIST_ID_PREFIX}`;
 | 
			
		||||
  }
 | 
			
		||||
  return org;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
function shouldSupportAnon() {
 | 
			
		||||
  // Enable UI for anonymous access if a flag is explicitly set in the environment
 | 
			
		||||
  return process.env.GRIST_SUPPORT_ANON === "true";
 | 
			
		||||
 | 
			
		||||
@ -306,6 +306,7 @@ describe('CellColor', function() {
 | 
			
		||||
    // Empty cell to clear error from converting toggle to date
 | 
			
		||||
    await cell.click();
 | 
			
		||||
    await driver.sendKeys(Key.DELETE);
 | 
			
		||||
    await gu.waitAppFocus(true);
 | 
			
		||||
 | 
			
		||||
    const clip = cell.find('.field_clip');
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@ -232,7 +232,7 @@ async function checkSelectingRecords(selectBy: string, sourceData: string[][], n
 | 
			
		||||
  for (let rowNum = 1; rowNum <= 3; rowNum++) {
 | 
			
		||||
    // Click an anchor link
 | 
			
		||||
    const anchorCell = gu.getCell({section: "Anchors", rowNum, col: 1});
 | 
			
		||||
    await anchorCell.find('.test-tb-link').click();
 | 
			
		||||
    await driver.withActions(a => a.click(anchorCell.find('.test-tb-link')));
 | 
			
		||||
 | 
			
		||||
    // Check that navigation to the link target worked
 | 
			
		||||
    assert.equal(await gu.getActiveSectionTitle(), "LINKTARGET");
 | 
			
		||||
 | 
			
		||||
@ -1,25 +1,26 @@
 | 
			
		||||
import * as _ from 'lodash';
 | 
			
		||||
import {addToRepl, assert, driver} from 'mocha-webdriver';
 | 
			
		||||
import {assert, driver} from 'mocha-webdriver';
 | 
			
		||||
import {enterRulePart, findDefaultRuleSet} from 'test/nbrowser/aclTestUtils';
 | 
			
		||||
import * as gu from 'test/nbrowser/gristUtils';
 | 
			
		||||
import {server, setupTestSuite} from 'test/nbrowser/testUtils';
 | 
			
		||||
import {setupTestSuite} from 'test/nbrowser/testUtils';
 | 
			
		||||
 | 
			
		||||
describe('SelectBySummary', function() {
 | 
			
		||||
  this.timeout(50000);
 | 
			
		||||
  setupTestSuite();
 | 
			
		||||
  addToRepl('gu2', gu);
 | 
			
		||||
  const cleanup = setupTestSuite();
 | 
			
		||||
  let headers: Record<string, string>;
 | 
			
		||||
  gu.bigScreen();
 | 
			
		||||
 | 
			
		||||
  before(async function() {
 | 
			
		||||
    await server.simulateLogin("Chimpy", "chimpy@getgrist.com", 'nasa');
 | 
			
		||||
    const doc = await gu.importFixturesDoc('chimpy', 'nasa', 'Horizon',
 | 
			
		||||
      'SelectBySummary.grist', false);
 | 
			
		||||
    await driver.get(`${server.getHost()}/o/nasa/doc/${doc.id}`);
 | 
			
		||||
    await gu.waitForDocToLoad();
 | 
			
		||||
    const session = await gu.session().teamSite.login();
 | 
			
		||||
    await session.tempDoc(cleanup, 'SelectBySummary.grist');
 | 
			
		||||
    headers = {
 | 
			
		||||
      Authorization: `Bearer ${session.getApiKey()}`
 | 
			
		||||
    };
 | 
			
		||||
  });
 | 
			
		||||
 | 
			
		||||
  it('should filter a source table selected by a summary table', async function() {
 | 
			
		||||
  it('should filter a source table selected by a summary table (first option)', async function() {
 | 
			
		||||
    await checkSelectingRecords(
 | 
			
		||||
      headers,
 | 
			
		||||
      ['onetwo'],
 | 
			
		||||
      [
 | 
			
		||||
        '1', '16',
 | 
			
		||||
@ -40,8 +41,11 @@ describe('SelectBySummary', function() {
 | 
			
		||||
        ],
 | 
			
		||||
      ],
 | 
			
		||||
    );
 | 
			
		||||
  });
 | 
			
		||||
 | 
			
		||||
  it('should filter a source table selected by a summary table (second option)', async function() {
 | 
			
		||||
    await checkSelectingRecords(
 | 
			
		||||
      headers,
 | 
			
		||||
      ['choices'],
 | 
			
		||||
      [
 | 
			
		||||
        'a', '14',
 | 
			
		||||
@ -67,9 +71,11 @@ describe('SelectBySummary', function() {
 | 
			
		||||
        ],
 | 
			
		||||
      ],
 | 
			
		||||
    );
 | 
			
		||||
  });
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
  it('should filter a source table selected by a summary table (both options)', async function() {
 | 
			
		||||
    await checkSelectingRecords(
 | 
			
		||||
      headers,
 | 
			
		||||
      ['onetwo', 'choices'],
 | 
			
		||||
      [
 | 
			
		||||
        '1', 'a', '6',
 | 
			
		||||
@ -104,7 +110,6 @@ describe('SelectBySummary', function() {
 | 
			
		||||
        ],
 | 
			
		||||
      ],
 | 
			
		||||
    );
 | 
			
		||||
 | 
			
		||||
  });
 | 
			
		||||
 | 
			
		||||
  it('should create new rows in the source table (link target) with correct default values',
 | 
			
		||||
@ -153,6 +158,7 @@ describe('SelectBySummary', function() {
 | 
			
		||||
    // selecting by the two less detailed summaries.
 | 
			
		||||
    // There was a bug previously that this would not work while the summary source table (Table1) was hidden.
 | 
			
		||||
    await checkSelectingRecords(
 | 
			
		||||
      headers,
 | 
			
		||||
      ['onetwo'],
 | 
			
		||||
      [
 | 
			
		||||
        '1', '16',
 | 
			
		||||
@ -175,6 +181,7 @@ describe('SelectBySummary', function() {
 | 
			
		||||
    );
 | 
			
		||||
 | 
			
		||||
    await checkSelectingRecords(
 | 
			
		||||
      headers,
 | 
			
		||||
      ['choices'],
 | 
			
		||||
      [
 | 
			
		||||
        'a', '14',
 | 
			
		||||
@ -208,6 +215,7 @@ describe('SelectBySummary', function() {
 | 
			
		||||
 * to the corresponding subarray of `targetData`.
 | 
			
		||||
 */
 | 
			
		||||
async function checkSelectingRecords(
 | 
			
		||||
  headers: Record<string, string>,
 | 
			
		||||
  groubyColumns: string[],
 | 
			
		||||
  summaryData: string[],
 | 
			
		||||
  targetData: string[][],
 | 
			
		||||
@ -243,7 +251,7 @@ async function checkSelectingRecords(
 | 
			
		||||
    );
 | 
			
		||||
    if (targetSection === 'TABLE1') {
 | 
			
		||||
      assert.equal(await countCell.getText(), numTargetRows.toString());
 | 
			
		||||
      const csvCells = await gu.downloadSectionCsvGridCells(targetSection);
 | 
			
		||||
      const csvCells = await gu.downloadSectionCsvGridCells(targetSection, headers);
 | 
			
		||||
      // visible cells text uses newlines to separate list items, CSV export uses commas
 | 
			
		||||
      const expectedCsvCells = targetGroup.map(s => s.replace("\n", ", "));
 | 
			
		||||
      assert.deepEqual(csvCells, expectedCsvCells);
 | 
			
		||||
@ -259,7 +267,7 @@ async function checkSelectingRecords(
 | 
			
		||||
    for (let rowNum = 1; rowNum <= 8; rowNum++) {
 | 
			
		||||
      // Click an anchor link
 | 
			
		||||
      const anchorCell = gu.getCell({section: "Anchors", rowNum, col: 1});
 | 
			
		||||
      await anchorCell.find('.test-tb-link').click();
 | 
			
		||||
      await driver.withActions(a => a.click(anchorCell.find('.test-tb-link')));
 | 
			
		||||
 | 
			
		||||
      // Check that navigation to the link target worked
 | 
			
		||||
      assert.equal(await gu.getActiveSectionTitle(), "TABLE1");
 | 
			
		||||
 | 
			
		||||
@ -61,6 +61,7 @@ export const uploadFixtureDoc = homeUtil.uploadFixtureDoc.bind(homeUtil);
 | 
			
		||||
export const getWorkspaceId = homeUtil.getWorkspaceId.bind(homeUtil);
 | 
			
		||||
export const listDocs = homeUtil.listDocs.bind(homeUtil);
 | 
			
		||||
export const createHomeApi = homeUtil.createHomeApi.bind(homeUtil);
 | 
			
		||||
export const getApiKey = homeUtil.getApiKey.bind(homeUtil);
 | 
			
		||||
export const simulateLogin = homeUtil.simulateLogin.bind(homeUtil);
 | 
			
		||||
export const removeLogin = homeUtil.removeLogin.bind(homeUtil);
 | 
			
		||||
export const enableTips = homeUtil.enableTips.bind(homeUtil);
 | 
			
		||||
@ -2047,6 +2048,13 @@ export class Session {
 | 
			
		||||
    return createHomeApi(this.settings.name, this.settings.orgDomain, this.settings.email);
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  public getApiKey(): string|null {
 | 
			
		||||
    if (this.settings.email === 'anon@getgrist.com') {
 | 
			
		||||
      return getApiKey(null);
 | 
			
		||||
    }
 | 
			
		||||
    return getApiKey(this.settings.name, this.settings.email);
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  // Get the id of this user.
 | 
			
		||||
  public async getUserId(): Promise<number> {
 | 
			
		||||
    await this.login();
 | 
			
		||||
 | 
			
		||||
@ -316,9 +316,14 @@ export class HomeUtil {
 | 
			
		||||
  // A helper to create a UserAPI instance for a given useranme and org, that targets the home server
 | 
			
		||||
  // Username can be null for anonymous access.
 | 
			
		||||
  public createHomeApi(username: string|null, org: string, email?: string): UserAPIImpl {
 | 
			
		||||
    const apiKey = this.getApiKey(username, email);
 | 
			
		||||
    return this._createHomeApiUsingApiKey(apiKey, org);
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  public getApiKey(username: string|null, email?: string): string | null {
 | 
			
		||||
    const name = (username || '').toLowerCase();
 | 
			
		||||
    const apiKey = username && ((email && this._apiKey.get(email)) || `api_key_for_${name}`);
 | 
			
		||||
    return this._createHomeApiUsingApiKey(apiKey, org);
 | 
			
		||||
    return apiKey;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  /**
 | 
			
		||||
 | 
			
		||||
@ -41,6 +41,7 @@ docker run --name $DOCKER_CONTAINER --rm \
 | 
			
		||||
  --env GRIST_LOG_LEVEL=$GRIST_LOG_LEVEL \
 | 
			
		||||
  --env GRIST_LOG_SKIP_HTTP=${DEBUG:-false} \
 | 
			
		||||
  --env TEST_SUPPORT_API_KEY=api_key_for_support \
 | 
			
		||||
  --env GRIST_TEMPLATE_ORG=templates \
 | 
			
		||||
  ${TEST_IMAGE:-gristlabs/grist} &
 | 
			
		||||
 | 
			
		||||
DOCKER_PID="$!"
 | 
			
		||||
 | 
			
		||||
		Loading…
	
		Reference in New Issue
	
	Block a user