Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 3 additions & 1 deletion src/main/java/graphql/i18n/I18n.java
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,9 @@ public enum BundleType {
protected I18n(BundleType bundleType, Locale locale) {
assertNotNull(bundleType);
assertNotNull(locale);
this.resourceBundle = ResourceBundle.getBundle(bundleType.baseName, locale);
// load the resource bundle with this classes class loader - to help avoid confusion in complicated worlds
// like OSGI
this.resourceBundle = ResourceBundle.getBundle(bundleType.baseName, locale, I18n.class.getClassLoader());
}

public ResourceBundle getResourceBundle() {
Expand Down
84 changes: 84 additions & 0 deletions src/test/groovy/graphql/i18n/I18nTest.groovy
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
package graphql.i18n

import graphql.AssertException
import graphql.ExecutionInput
import graphql.TestUtil
import graphql.i18n.I18n.BundleType
import spock.lang.Specification

Expand All @@ -26,6 +28,88 @@ class I18nTest extends Specification {
}
}


def "missing resource bundles default to a base version"() {
// see https://saimana.com/list-of-country-locale-code/

def expected = "Validation error ({0}) : Type '{1}' definition is not executable"

when:
def i18n = I18n.i18n(BundleType.Validation, Locale.ENGLISH)
def msg = i18n.msg("ExecutableDefinitions.notExecutableType")

then:
msg == expected

when:
i18n = I18n.i18n(BundleType.Validation, Locale.CHINESE)
msg = i18n.msg("ExecutableDefinitions.notExecutableType")
then:
msg == expected

when:
i18n = I18n.i18n(BundleType.Validation, new Locale("en", "IN")) // India
msg = i18n.msg("ExecutableDefinitions.notExecutableType")
then:
msg == expected

when:
i18n = I18n.i18n(BundleType.Validation, new Locale("en", "FJ")) // Fiji
msg = i18n.msg("ExecutableDefinitions.notExecutableType")
then:
msg == expected

when:
i18n = I18n.i18n(BundleType.Validation, new Locale("")) // Nothing
msg = i18n.msg("ExecutableDefinitions.notExecutableType")
then:
msg == expected
}

def "integration test of valid messages"() {
def sdl = """
type Query {
field(arg : Int) : Subselection
}

type Subselection {
name : String
}
"""
def graphQL = TestUtil.graphQL(sdl).build()


when:
def locale = new Locale("en", "IN")
def ei = ExecutionInput.newExecutionInput().query("query missingSubselectionQ { field(arg : 1) }")
.locale(locale)
.build()
def er = graphQL.execute(ei)
then:
!er.errors.isEmpty()
er.errors[0].message == "Validation error (SubselectionRequired@[field]) : Subselection required for type 'Subselection' of field 'field'"


when:
locale = Locale.getDefault()
ei = ExecutionInput.newExecutionInput().query("query missingSubselectionQ { field(arg : 1) }")
.locale(locale)
.build()
er = graphQL.execute(ei)
then:
!er.errors.isEmpty()
er.errors[0].message == "Validation error (SubselectionRequired@[field]) : Subselection required for type 'Subselection' of field 'field'"

when:
// no locale - it should default
ei = ExecutionInput.newExecutionInput().query("query missingSubselectionQ { field(arg : 1) }")
.build()
er = graphQL.execute(ei)
then:
!er.errors.isEmpty()
er.errors[0].message == "Validation error (SubselectionRequired@[field]) : Subselection required for type 'Subselection' of field 'field'"
}

static def assertBundleStaticShape(ResourceBundle bundle) {
def enumeration = bundle.getKeys()
while (enumeration.hasMoreElements()) {
Expand Down