Skip to content

Commit f1d2316

Browse files
authored
Merge branch 'alpha' into moumouls/update-push-adapter
2 parents 0065aac + 3ca85cd commit f1d2316

11 files changed

Lines changed: 773 additions & 90 deletions

package-lock.json

Lines changed: 179 additions & 79 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,7 @@
3030
"commander": "13.1.0",
3131
"cors": "2.8.5",
3232
"deepcopy": "2.1.0",
33-
"express": "5.1.0",
33+
"express": "5.2.1",
3434
"express-rate-limit": "7.5.1",
3535
"follow-redirects": "1.15.9",
3636
"graphql": "16.11.0",

resources/buildConfigDefinitions.js

Lines changed: 17 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -155,6 +155,8 @@ function mapperFor(elt, t) {
155155
return wrap(t.identifier('objectParser'));
156156
} else if (t.isBooleanTypeAnnotation(elt)) {
157157
return wrap(t.identifier('booleanParser'));
158+
} else if (t.isObjectTypeAnnotation(elt)) {
159+
return wrap(t.identifier('objectParser'));
158160
} else if (t.isGenericTypeAnnotation(elt)) {
159161
const type = elt.typeAnnotation.id.name;
160162
if (type == 'Adapter') {
@@ -372,12 +374,18 @@ This code has been generated by resources/buildConfigDefinitions.js
372374
Do not edit manually, but update Options/index.js
373375
`;
374376

375-
const babel = require('@babel/core');
376-
const res = babel.transformFileSync('./src/Options/index.js', {
377-
plugins: [plugin, '@babel/transform-flow-strip-types'],
378-
babelrc: false,
379-
auxiliaryCommentBefore,
380-
sourceMaps: false,
381-
});
382-
require('fs').writeFileSync('./src/Options/Definitions.js', res.code + '\n');
383-
require('fs').writeFileSync('./src/Options/docs.js', docs);
377+
// Only run the transformation when executed directly, not when imported by tests
378+
if (require.main === module) {
379+
const babel = require('@babel/core');
380+
const res = babel.transformFileSync('./src/Options/index.js', {
381+
plugins: [plugin, '@babel/transform-flow-strip-types'],
382+
babelrc: false,
383+
auxiliaryCommentBefore,
384+
sourceMaps: false,
385+
});
386+
require('fs').writeFileSync('./src/Options/Definitions.js', res.code + '\n');
387+
require('fs').writeFileSync('./src/Options/docs.js', docs);
388+
}
389+
390+
// Export mapperFor for testing
391+
module.exports = { mapperFor };

spec/ParseGraphQLServer.spec.js

Lines changed: 278 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7080,6 +7080,284 @@ describe('ParseGraphQLServer', () => {
70807080
});
70817081
});
70827082

7083+
describe("Config Queries", () => {
7084+
beforeEach(async () => {
7085+
// Setup initial config data
7086+
await Parse.Config.save(
7087+
{ publicParam: 'publicValue', privateParam: 'privateValue' },
7088+
{ privateParam: true },
7089+
{ useMasterKey: true }
7090+
);
7091+
});
7092+
7093+
it("should return the config value for a specific parameter", async () => {
7094+
const query = gql`
7095+
query cloudConfig($paramName: String!) {
7096+
cloudConfig(paramName: $paramName) {
7097+
value
7098+
isMasterKeyOnly
7099+
}
7100+
}
7101+
`;
7102+
7103+
const result = await apolloClient.query({
7104+
query,
7105+
variables: { paramName: 'publicParam' },
7106+
context: {
7107+
headers: {
7108+
'X-Parse-Master-Key': 'test',
7109+
},
7110+
},
7111+
});
7112+
7113+
expect(result.errors).toBeUndefined();
7114+
expect(result.data.cloudConfig.value).toEqual('publicValue');
7115+
expect(result.data.cloudConfig.isMasterKeyOnly).toEqual(false);
7116+
});
7117+
7118+
it("should return null for non-existent parameter", async () => {
7119+
const query = gql`
7120+
query cloudConfig($paramName: String!) {
7121+
cloudConfig(paramName: $paramName) {
7122+
value
7123+
isMasterKeyOnly
7124+
}
7125+
}
7126+
`;
7127+
7128+
const result = await apolloClient.query({
7129+
query,
7130+
variables: { paramName: 'nonExistentParam' },
7131+
context: {
7132+
headers: {
7133+
'X-Parse-Master-Key': 'test',
7134+
},
7135+
},
7136+
});
7137+
7138+
expect(result.errors).toBeUndefined();
7139+
expect(result.data.cloudConfig.value).toBeNull();
7140+
expect(result.data.cloudConfig.isMasterKeyOnly).toBeNull();
7141+
});
7142+
});
7143+
7144+
describe("Config Mutations", () => {
7145+
it("should update a config value using mutation and retrieve it with query", async () => {
7146+
const mutation = gql`
7147+
mutation updateCloudConfig($input: UpdateCloudConfigInput!) {
7148+
updateCloudConfig(input: $input) {
7149+
clientMutationId
7150+
cloudConfig {
7151+
value
7152+
isMasterKeyOnly
7153+
}
7154+
}
7155+
}
7156+
`;
7157+
7158+
const query = gql`
7159+
query cloudConfig($paramName: String!) {
7160+
cloudConfig(paramName: $paramName) {
7161+
value
7162+
isMasterKeyOnly
7163+
}
7164+
}
7165+
`;
7166+
7167+
const mutationResult = await apolloClient.mutate({
7168+
mutation,
7169+
variables: {
7170+
input: {
7171+
clientMutationId: 'test-mutation-id',
7172+
paramName: 'testParam',
7173+
value: 'testValue',
7174+
isMasterKeyOnly: false,
7175+
},
7176+
},
7177+
context: {
7178+
headers: {
7179+
'X-Parse-Master-Key': 'test',
7180+
},
7181+
},
7182+
});
7183+
7184+
expect(mutationResult.errors).toBeUndefined();
7185+
expect(mutationResult.data.updateCloudConfig.cloudConfig.value).toEqual('testValue');
7186+
expect(mutationResult.data.updateCloudConfig.cloudConfig.isMasterKeyOnly).toEqual(false);
7187+
7188+
const queryResult = await apolloClient.query({
7189+
query,
7190+
variables: { paramName: 'testParam' },
7191+
context: {
7192+
headers: {
7193+
'X-Parse-Master-Key': 'test',
7194+
},
7195+
},
7196+
});
7197+
7198+
expect(queryResult.errors).toBeUndefined();
7199+
expect(queryResult.data.cloudConfig.value).toEqual('testValue');
7200+
expect(queryResult.data.cloudConfig.isMasterKeyOnly).toEqual(false);
7201+
});
7202+
7203+
it("should update a config value with isMasterKeyOnly set to true", async () => {
7204+
const mutation = gql`
7205+
mutation updateCloudConfig($input: UpdateCloudConfigInput!) {
7206+
updateCloudConfig(input: $input) {
7207+
clientMutationId
7208+
cloudConfig {
7209+
value
7210+
isMasterKeyOnly
7211+
}
7212+
}
7213+
}
7214+
`;
7215+
7216+
const query = gql`
7217+
query cloudConfig($paramName: String!) {
7218+
cloudConfig(paramName: $paramName) {
7219+
value
7220+
isMasterKeyOnly
7221+
}
7222+
}
7223+
`;
7224+
7225+
const mutationResult = await apolloClient.mutate({
7226+
mutation,
7227+
variables: {
7228+
input: {
7229+
clientMutationId: 'test-mutation-id-2',
7230+
paramName: 'privateTestParam',
7231+
value: 'privateValue',
7232+
isMasterKeyOnly: true,
7233+
},
7234+
},
7235+
context: {
7236+
headers: {
7237+
'X-Parse-Master-Key': 'test',
7238+
},
7239+
},
7240+
});
7241+
7242+
expect(mutationResult.errors).toBeUndefined();
7243+
expect(mutationResult.data.updateCloudConfig.cloudConfig.value).toEqual('privateValue');
7244+
expect(mutationResult.data.updateCloudConfig.cloudConfig.isMasterKeyOnly).toEqual(true);
7245+
7246+
const queryResult = await apolloClient.query({
7247+
query,
7248+
variables: { paramName: 'privateTestParam' },
7249+
context: {
7250+
headers: {
7251+
'X-Parse-Master-Key': 'test',
7252+
},
7253+
},
7254+
});
7255+
7256+
expect(queryResult.errors).toBeUndefined();
7257+
expect(queryResult.data.cloudConfig.value).toEqual('privateValue');
7258+
expect(queryResult.data.cloudConfig.isMasterKeyOnly).toEqual(true);
7259+
});
7260+
7261+
it("should update an existing config value", async () => {
7262+
await Parse.Config.save(
7263+
{ existingParam: 'initialValue' },
7264+
{},
7265+
{ useMasterKey: true }
7266+
);
7267+
7268+
const mutation = gql`
7269+
mutation updateCloudConfig($input: UpdateCloudConfigInput!) {
7270+
updateCloudConfig(input: $input) {
7271+
clientMutationId
7272+
cloudConfig {
7273+
value
7274+
isMasterKeyOnly
7275+
}
7276+
}
7277+
}
7278+
`;
7279+
7280+
const query = gql`
7281+
query cloudConfig($paramName: String!) {
7282+
cloudConfig(paramName: $paramName) {
7283+
value
7284+
isMasterKeyOnly
7285+
}
7286+
}
7287+
`;
7288+
7289+
const mutationResult = await apolloClient.mutate({
7290+
mutation,
7291+
variables: {
7292+
input: {
7293+
clientMutationId: 'test-mutation-id-3',
7294+
paramName: 'existingParam',
7295+
value: 'updatedValue',
7296+
isMasterKeyOnly: false,
7297+
},
7298+
},
7299+
context: {
7300+
headers: {
7301+
'X-Parse-Master-Key': 'test',
7302+
},
7303+
},
7304+
});
7305+
7306+
expect(mutationResult.errors).toBeUndefined();
7307+
expect(mutationResult.data.updateCloudConfig.cloudConfig.value).toEqual('updatedValue');
7308+
7309+
const queryResult = await apolloClient.query({
7310+
query,
7311+
variables: { paramName: 'existingParam' },
7312+
context: {
7313+
headers: {
7314+
'X-Parse-Master-Key': 'test',
7315+
},
7316+
},
7317+
});
7318+
7319+
expect(queryResult.errors).toBeUndefined();
7320+
expect(queryResult.data.cloudConfig.value).toEqual('updatedValue');
7321+
});
7322+
7323+
it("should require master key to update config", async () => {
7324+
const mutation = gql`
7325+
mutation updateCloudConfig($input: UpdateCloudConfigInput!) {
7326+
updateCloudConfig(input: $input) {
7327+
clientMutationId
7328+
cloudConfig {
7329+
value
7330+
isMasterKeyOnly
7331+
}
7332+
}
7333+
}
7334+
`;
7335+
7336+
try {
7337+
await apolloClient.mutate({
7338+
mutation,
7339+
variables: {
7340+
input: {
7341+
clientMutationId: 'test-mutation-id-4',
7342+
paramName: 'testParam',
7343+
value: 'testValue',
7344+
isMasterKeyOnly: false,
7345+
},
7346+
},
7347+
context: {
7348+
headers: {
7349+
'X-Parse-Application-Id': 'test',
7350+
},
7351+
},
7352+
});
7353+
fail('Should have thrown an error');
7354+
} catch (error) {
7355+
expect(error.graphQLErrors).toBeDefined();
7356+
expect(error.graphQLErrors[0].message).toContain('Permission denied');
7357+
}
7358+
});
7359+
})
7360+
70837361
describe('Users Queries', () => {
70847362
it('should return current logged user', async () => {
70857363
const userName = 'user1',

0 commit comments

Comments
 (0)