diff --git a/Dockerfile b/Dockerfile index 5ddaf4f54..8454b5530 100644 --- a/Dockerfile +++ b/Dockerfile @@ -5,7 +5,11 @@ WORKDIR /app # Copy source COPY . ./ -# Publish +# Build project and run tests +RUN dotnet build && \ + find test -path "*/bin/*Test.dll" -type f -print0 |xargs -0 dotnet vstest --parallel + +# Publish release project RUN dotnet publish -c Release -o "/app/publish/" # Get runtime image diff --git a/GreatReadingAdventure.sln b/GreatReadingAdventure.sln index f89dde7f6..a3a702ec2 100644 --- a/GreatReadingAdventure.sln +++ b/GreatReadingAdventure.sln @@ -16,6 +16,7 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution global.json = global.json GRARuleSet.ruleset = GRARuleSet.ruleset README.md = README.md + TestSettings.testsettings = TestSettings.testsettings EndProjectSection EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "GRA.Web", "src\GRA.Web\GRA.Web.csproj", "{62E47447-A4E5-40FC-8CA7-12A0FBE46915}" @@ -55,6 +56,10 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "dev", "dev", "{2F931D25-1A2 dev\README.md = dev\README.md EndProjectSection EndProject +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "test", "test", "{44008A86-CC39-4EBF-A806-C391F4D8CB55}" +EndProject +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "GRA.Test", "test\GRA.Test\GRA.Test.csproj", "{4DF3AA9C-29B7-4BE6-9CE4-28B3785321F7}" +EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Any CPU = Debug|Any CPU @@ -109,6 +114,10 @@ Global {05C5D3BB-DFFC-44EB-8A8B-C5B9D5A6448B}.Debug|Any CPU.Build.0 = Debug|Any CPU {05C5D3BB-DFFC-44EB-8A8B-C5B9D5A6448B}.Release|Any CPU.ActiveCfg = Release|Any CPU {05C5D3BB-DFFC-44EB-8A8B-C5B9D5A6448B}.Release|Any CPU.Build.0 = Release|Any CPU + {4DF3AA9C-29B7-4BE6-9CE4-28B3785321F7}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {4DF3AA9C-29B7-4BE6-9CE4-28B3785321F7}.Debug|Any CPU.Build.0 = Debug|Any CPU + {4DF3AA9C-29B7-4BE6-9CE4-28B3785321F7}.Release|Any CPU.ActiveCfg = Release|Any CPU + {4DF3AA9C-29B7-4BE6-9CE4-28B3785321F7}.Release|Any CPU.Build.0 = Release|Any CPU EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE @@ -128,6 +137,7 @@ Global {E8041040-29F4-43F7-A9DF-EFCED64B22F0} = {0324DE44-14C1-4203-A624-5BE8BD75153E} {1014D7A4-CAB9-4F28-9F83-F0083DC7A90A} = {0324DE44-14C1-4203-A624-5BE8BD75153E} {05C5D3BB-DFFC-44EB-8A8B-C5B9D5A6448B} = {6BA5FF75-C5CE-45BC-8836-B2E689A571A1} + {4DF3AA9C-29B7-4BE6-9CE4-28B3785321F7} = {44008A86-CC39-4EBF-A806-C391F4D8CB55} EndGlobalSection GlobalSection(ExtensibilityGlobals) = postSolution SolutionGuid = {DF823FBB-4DD0-4907-9298-E01FB3497962} diff --git a/TestSettings.testsettings b/TestSettings.testsettings new file mode 100644 index 000000000..701ab5b10 --- /dev/null +++ b/TestSettings.testsettings @@ -0,0 +1,27 @@ + + + These are default test settings for a local test run. + + + + + + + + + + + +
+
+
+
+ + + + + + + + + \ No newline at end of file diff --git a/src/GRA/Resources/Shared.en.resx b/src/GRA/Resources/Shared.en.resx index de60f0db2..d30287f45 100644 --- a/src/GRA/Resources/Shared.en.resx +++ b/src/GRA/Resources/Shared.en.resx @@ -1,6 +1,6 @@  - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - text/microsoft-resx - - - 2.0 - - - System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + Age Prompt for a participant's age in years. - + Author Dashboard prompt for entering a book author - + Authorization Code A code used to grant more privileges to an administrative user - + Branch Prompt for a participant's library branch from a drop-down list, examples might be 'Aguila Library' or 'Mesquite Library' or 'Sunset Library' - + Challenges Navigation bar link to Challenges - + Charter School A school type - charter school - + Confirm New Password Prompt for a participant to enter their new password again to ensure they did not make a typo. - + Confirm Password Prompt for a participant to enter their password again to ensure they did not make a typo. - + Could not create your account: {0} Error creating the participant's account, {0} is replaced with the explanation as to why - + Could not find username '{0}'. Could not find a username when a participant is trying to authenticate. - + Secret codes can be found by attending library events and on promotional materials. If you find one, enter it below! Dashboard explanation of what secret codes are - + Email Address Prompt for a participant's email address - + Email and Phone Number are not required however at least one is needed in order to be eligible for prizes. Explanation about contact information being necessary to win prizes. - + Enter {0} read Dashboard entry of activity performed, {0} is plural (for example "minutes" or "pages") - + Events Navigation bar link to Events - + First Name Prompt for a participant's first name (given name, forename, Christian name) - + Forgot Password Title of the page for sending a participant their password recovery link - + Forgot your password? Link for a participant to click if they've forgotten their password - + Forgot your username? Link for a participant to click if they've forgotten their username - + Home Navigation bar link to home page - + Homeschooled A school type - homeschooled - + I read a book! Dashboard button for logging activity of reading one book - + I will {0} Daily personal goal, an explanation of activity, {0} is the action such as "read". See '{0} a day' for completion of this sentence - when combined they will say something similar to "I will read _ minutes a day" - + Is this your first time participating? Prompt for a participant about if this is their first time participating in the program. - + This website relies on JavaScript. Please enable JavaScript in your browser to get the best experience. Text to display if the user's browser does not have JavaScript functional - + Join Navigation bar link or page title for join/sign up - + Join! Text of the button to create a participant account - + Language Navigation bar drop-down for language selection - + Last Name Prompt for a participant's last name (surname, family name) - + Log {0} Dashboard submit button for activity performed, {0} is plural (for example "minutes" or "pages") - + Mail Navigation bar link to in-software mail facility - + Menu Text for display when the window is small to expand the top navigation bar - + Mission Control Navigation bar link to system administration area (colloquially how NASA refers to the mission control center/operations center) - + My Profile Navigation bar link to the participant's user profile - + New Password Prompt for a participant's new password - + No No, negative response to inquiry - + Once the program starts, you will enter your activity right here! Dashboard explanation that the program hasn't started yet and what to do once it has - + Participate in program activities to earn badges! Dashboard text displayed when the participant has no badges. - + Password Prompt for a participant's password to access the system. - + Password and password confirmation do not match. Validation prompt explaining that the password and password confirmation fields do not match. - + Password Recovery Title of the page for allowing a participant to reset their password - + Permission denied. General message when a participant does not have permission to execute an action. - + Phone Number Prompt for a participant's telephone number - + Please correct the issues with your password. Validation prompt if there are issues with the participant's password on the join form. - + Please let us know if this is your first time participating in the program. Validation prompt if the participant did not select whether or not this is their first time participating in the program. - + Please let us know if you would like to receive emails throughout the program. Validation prompt if the participant did not select whether or not they want to receive periodic emails during the program. - + Please select a branch. Validation prompt if the participant did not select a library branch. - + Please select a program. Validation prompt if no value was selected for the program from a drop-down and it's required, examples might be 'Adult' or 'Teen' - the context is that of a summer or winter library reading program - + Please select a system. Validation prompt if the participant did not select a library system. - + Please select a value for {0}. No value was selected for the field and it's required, {0} is the field name (such as 'System' or 'Branch') - + Private School A school type - private school - + Program Prompt for a participant's program selection from a drop-down list, examples might be 'Adult' or 'Teen' - the context is that of a summer or winter library reading program - + Public School A school type - public school - + Registration for {0} is not open yet. Alert shown to a participant if they attempt to join prior to registration opening for the program; {0} is the name of the program - + Reset Password Button to save a participant's new password - + Return to Sign In Button to take a participant back to the sign in page - + School Prompt for the name of the participant's school - + School District Prompt for a participant's school district - + School not listed Prompt for a participant indicating their school is not listed - + School Type Prompt for a participant's school type - + Secret Code Dashboard prompt for entering a secret code - + See more of your badges in your history! Dashboard link to view participant's history, displayed underneath their badges - + See your activity history. Dashboard link to view history of program activities - + Send Recovery Email Button to send a user their username or password recovery email - + Set a personal goal Prompt participant for a personal goal when participating in the program - + Sign in Navigation bar link to sign in/authenticate - + Sign out Navigation bar link to sign out - + Someone has already chosen that username, please try another. Validation prompt if the username is already in use. - + Step {0} Which step of a process we are on, {0} is replaced with a number like 1, 2, or 3 - + Submit Code Dashboard button to submit a secret code - + System Prompt for a participant's library system from a drop-down list, examples might be 'Maricopa County Library District' or 'Phoenix Public Library' - + That username is available! Validation prompt that the username selected is available. - + The branch you've selected is not valid, please select another branch. The participant has selected a branch that is not valid. This should not occur but could happen if a branch became invalid while they were signing up. - + The program has ended, thanks for participating! Dashboard information about the program ending. - + The program is not accepting registrations at this time. A participant tried to sign up when the program was not open for sign-ups. - + The program is not open for activity at this time. A participant tried to enter activity when the program was not permitting it. - + The program you've selected is not valid, please select another program. The participant has selected a program that is not valid. This should not occur but could happen if a program became invalid while they were signing up. - + The school you've selected is not valid, please select another school. The participant has selected a school that is not valid. This should not occur but could happen if a school became invalid while they were signing up. - + The system you've selected is not valid, please select another system. The participant has selected a system that is not valid. This should not occur but could happen if a system became invalid while they were signing up. - + Please provide a value for {0}. No value was entered for the field and it's required, {0} is the field name (such as 'First Name') - + This program may be better-suited to your age: Validation prompt that the user should perhaps select another program - this text is followed by the name of the recommended program. - + Title Dashboard prompt for entering a book title - + To receive email updates please supply an email address to send them to. Validation prompt if the participant requested email updates but neglected to provide an email address. - + Toggle navigation Text for screen readers when the window is small to expand the top navigation when it is collapsed - + Token A set of characters that a participant enters to verify their identity, typically alphanumeric - + Username Prompt for a participant's unique username which is used to access the system. - + Username Recovery Title of the page for sending a participant their username if they've forgotten it - + Validate code Text of the button used to validate an Authorization Code - + Welcome <strong>{0}!</strong> Dashboard friendly greeting, {0} is the participant's first name - + Yes Yes, positive response to inquiry - + You can join {0} on {1}. Alert shown to a participant if they attempt to join prior to the start of the program; {0} is the name of the program, {1} is a the date the program starts - + You have <strong>{0}</strong> points. Dashboard display of current points, {0} is a number of points they've earned - + Your badges Dashboard link to view participant's history, displayed above their badges on the dashboard - + Your password must be at least 6 characters long and include a number. Password requirements shown to participants. - + + Joined {0}! + Confirmation to the participant that they have joined the program. {0} is replaced with the name of the program. + + + When you complete <strong>{0}</strong>, you will earn <strong>{1}</strong> and a badge. + Inform the participant that when they complete a task, they receive a reward and a badge. {0} is the task, {1} is the reward. + + + When you complete <strong>{0}</strong>, you will earn <strong>{1}</strong>. + Inform the participant that when they complete a task, they receive a reward. {0} is the task, {1} is the reward. + + + Thanks for participating in {0}! + Thank visitors for participating in the program. {0} is replaced with the name of the program. + + + You can still sign in to review your history and achievements. + Inform the participant that they can review the records of their participation and their accomplishments by signing in. + + ZIP Code Prompt for a participant's ZIP code or postal code - + {0} - Join Now! Page title/call to action for joining; {0} is the name of the program - + {0} a day Daily personal goal, completion of sentence, {0} is a plural activity description such as "minutes". See 'I will {0}' for the first half of this sentence - when combined they will say something similar to "I will read _ minutes a day" - + {0} has ended, please join us next time! Alert shown to a participant if they access after the program has ended; {0} is the name of the program - + A list of usernames associated with the email address '{0}' has been sent. Informing the user that a list of usernames email has been sent; {0} is the associated email address - + A password recovery email has been sent to the email for username '{0}'. Informing the user that a password recovery email has been sent; {0} is their username - + Could not recover username(s): {0} A username recovery email could not be sent for the reason specified in {0} - + Password reset for: {0} Telling the user that their password was reset, {0} is their username - + Password reset token '{0}' has expired, please start the password reset process over. Password reset token has expired because the user waited too long between asking to reset their password and clicking the link. They must restart the password reset process and generate a new token. - + Password reset token '{0}' is not valid, please start the password reset process over. Password reset token is not valid, they must restart the password reset process and generate a new token. - + The program is not accepting sign-ins at this time. A participant tried to sign in when the program was not open for sign-ins. - + The provided password is incorrect. Validation prompt that the user entered an invalid password. - + There are no usernames associated with the email address: {0}. An attempt was made to find usernames associated with an email address and none were found; {0} is the email address that was searched for - + Unable to reset password: {0} Telling the user why their password could not be reset, {0} is the explanation - + Username '{0}' does not have an email address configured. The user does not have an email address configured so we cannot email them to perform a password reset; {0} is their username - + Please enter a whole number greater than 0. Validation prompt if the participant entered a non-integer, number less than 0, or 0. - + When providing an author of a book, please also provide a title. Validation prompt if the participant entered an author but not the title of a book. - + Sorry, we couldn't log your activity: {0} Due to a software problem, the participant's activity could not be saved. - + Thanks! We'll let you know when you can join the program. Inform the participant that we will email them when they can participate in the program. - + Please enter less than {1} characters for {0}. Validation prompt that a particular field - name replaces {0} - has a maximum allowed length of characters - replaced by {1}. - + Please enter more than {1} characters for {0}. Validation prompt that a particular field - name replaces {0} - has a minimum allowed length of characters - replaced by {1}. - + The {0} field is not a valid email address. Validation prompt for an invalid email address. - + The {0} field is not a valid phone number. Validation prompt for an invalid telephone number. - + Join Now! Shown on top of join page as participant signs up for the program after the name of the program and a hyphen (e.g. "The Great Reading Adventure - <this message>") - + My progress Display prior to progress bar showing the participant's progress in the program - + Final Step Text inside a button to indicate clicking takes the user to the last step of a multi-step process. - + Next Step Text inside a button to indicate clicking takes the user to the next step of a multi-step process. Often pictured next to a right arrow. - + The password you've provided is too short, it must be at least {0} characters long. Password provided is two short, {0} will be replaced with the required number of characters. - + You must include a lowercase letter in your password. Password provided does not contain a lowercase letter and must contain at least one. - + You must include a number in your password. Password provided does not contain a digit and must contain at least one. - + You must include a special character in your password. Password provided does not contain any symbols (e.g. !, @, #) and must contain at least one. - + You must include an uppercase letter in your password. Password provided does not contain an uppercase letter and must contain at least one. - + The goal of this program is {0} points. Inform the user how many points are required to reach the goal of the program, {0} is replaced with a number of points. - + The username and password entered do not match. Prompt the user that the username and password entered are not accurate. - + Sign in to {0} Prompt a user to sign in to the site, {0} is replaced with the name of the site - + Remind Me! Submission button text for the participant's email address to be reminded prior to the program starting. - + Submit your email address below and we'll remind you when the program starts. Prompt for a participant's email to send a reminder when the program starts. - + Add a calendar reminder Landing page button to download a calendar reminder file (when opened it will add a calendar reminder on the visitor's computer) - + For more information about this reading program, visit your local library! Landing page call to action for learning more - + Join to get started on your reading adventure! Landing page text encouraging registration once the program has started. - + Our program starts soon but you can join now to be ready to go when the program starts! Landing page text encouraging registration once registration is open but prior to the program start date. - + Reading for 20 minutes a day helps build a strong lifelong reading habit. Landing page message to encourage reading 20 minutes a day. - + Reading is fundamental for developing literacy skills! Landing page message informing that reading is fundamental for developing literacy skills. - + Thanks for participating in {0}. You can still sign in to review your history and achievements. - Landing page text thanking visitors for participating after the program has ended when they can still log in to see their history and achievements. + Landing page text thanking visitors for participating after the program has ended when they can still log in to see their history and achievements. {0} is replaced with the name of the program. - + Welcome to {0}. Landing page welcome text; {0} is replaced with the name of the site. - + When the program starts, you'll be able to join right here. Come back soon! Landing page message to show visitors when the start date of the program isn't specified. - + While you're there, go on a journey of discovery! Visit fabulous destinations such as Hogwarts, Narnia, Oz, and Middle Earth! Landing page after the call to action for learning more; things to experience at the library - + Would you like a reminder email for our next reading program? Enter your email address below and click the 'Remind me' button and we'll send you a reminder when you can join. Landing page text asking if visitors want a reminder for the next program. - + You can join our program starting on {0}! Landing page message to show visitors when the start date of the program is; {0} is replaced with the start date of the program. - + You must enter a code! Validation prompt if the user clicked the secret code submission button without entering a secret code. - + Can we send you a few emails throughout the program? Prompt as to whether or not emails can be sent throughout the program - this is user configurable so it may not match - + All Programs Select all programs in a program selection drop-down list - + Clear Button text to clear out entries from a form - + Community Experiences Name for community experiences - + Distance Column title showing events: approximate distance from the search location - + End Date Prompt to select an ending date for a date range - + Enter an address or ZIP code Prompt to enter an address or ZIP code to search for events - + Enter text to search for an event here Prompt to enter text to search for events - + Events & Community Experiences Page title for showing Events and Community Experiences - + Find Button text to perform a search - + Location Prompt to select the name of a location - + Near Location Prompt to search for items near this location - + No Events Explain that no matching events were found when a search was performed - + Search Title & Description Prompt to search by title and description - + Start Date Prompt to select a beginning date for a date range - + What Column title showing events: what the event is - + When Column title showing events: when the event occurs - + Where Column title showing events: where the event occurs - + {0} at {1} When an event is at a specific time on a date it will displayed using this template; {0} is the date, {1} is the time - + {0} mile(s) Express a distance; {0} replaced with the number of mile(s) - + Use my ZIP code Button text when searching to use the current participant's ZIP code - + Avatar A representation of the participant that they can customize (e.g. with different outfits or accessories) - + Avatar saved. Tell the participant that their avatar changes have been saved. - + Back Navigate back to the prior page - + Back to Challenges Button text to return to the list of challenges - + Badge Column heading showing which badge will be unlocked when a task is completed - + Category Prompt or display title for which category an item is in (such as a challenge) - + Challenge Group: {0} Display which challenge group was selected; {0} is replaced with the name of the challenge group - + Challenge: {0} Page title for viewing the details of a specific challenge; {0} will be replaced with the name of the challenge - + Completed on: {0} Challenge task completion date, {0} is replaced with the date the task was completed - + Completed! Status to show when a challenge or challenge task is marked complete. - + Could not save avatar: {0} Tell the participant that we could not save their avatar changes, {0} will be replaced with a reason why - + Couldn't save your avatar, sorry! Apologize to the user for a technical problem while saving their customized avatar. - + Download to Share Download an image in order to share it on social media platforms - + Enter text to search for a challenge here Prompt to enter text to search for challenges - + My Favorites Button which will display to a participant items that they flagged as their favorites - + Name Column heading for the name of an item (like a challenge or an event) - + No Challenges Explain that no matching challenges were found when a search was performed - + Please customize your avatar and save it, then you can share it! Participant has tried to share their avatar before saving it, inform them they must customize and save it first and then they can try sharing it. - + Points you'll earn Column heading showing many points a participant will earn for completing a task - + Progress Column heading showing far a participant is towards completing an item (i.e. their progress) - + Read <strong><em><a href=\"{0}\" target=\"_blank\">{1}</a></em></strong> Challenge task of book with a link (replacing {0}) and a book title (replacing {1}) - + Read <strong><em><a href=\"{0}\" target=\"_blank\">{1}</a></em></strong> by <strong>{2}</strong> Challenge task of book with a link (replacing {0}), a book title (replacing {1}) and the author of the book (replacing {2}) - + Read <strong><em>{0}</em></strong> Challenge tasks of book with the book title replacing {0} - + Read <strong><em>{0}</em></strong> by <strong>{1}</strong> Challenge task of a book with the book title replacing {0} and the author replacing {1} - + Save Button text for saving changes - + Save My Favorites Button allowing a participant to save their selected favorites - + Share Button text for sharing avatar images - + Share Your Avatar Title for the avatar sharing page - + View Attachment Button text to view an attached file to a challenge task - - When you complete <strong>{0}</strong>, you will earn <strong>{1}</strong> and a badge. - Describe what completing a challenge will achieve. {0} replaced with singular or plural task information (e.g. "1 task"or "2 tasks") and {1} is replaced with singular or plural point information (e.g. "1 point" or "2 points") - - - When you complete <strong>{0}</strong>, you will earn <strong>{1}</strong>. - Describe what completing a challenge will achieve. {0} replaced with singular or plural task information (e.g. "1 task"or "2 tasks") and {1} is replaced with singular or plural point information (e.g. "1 point" or "2 points") - - + Your status has been saved! Participant's status on completing tasks has been saved. - + Your status has been saved. You have completed {0}% of the required tasks for the challenge: {1}! Participant's status on completing tasks has been saved, {0} replaced with the percentage of the required tasks which have been completed and {1} is replaced with the name of the challenge. - + {0} point Indicating a single point, {0} will be replaced with 1 - + {0} points Indicating a number of points other than 1, {0} will be replaced with 0 or a number more than 1 - + {0} task Indicating a single challenge task, {0} will be replaced with 1 - + {0} tasks Indicating a number of challenge tasks other than 1, {0} will be replaced with 0 or a number more than 1 - + Back to Events & Community Experiences Button text for returning to the list of events or community experiences - + More information Text shown before a link to an external site where the user can find more information about an event - + Related Challenge Text shown before a link to challenge related to a shown event - + Related Challenges Text shown before a link to multiple challenges related to a shown event - + This event is limited to the program: {0} Shown to a user when an event is limited to a specific program. - + You are now unsubscribed and will not receive any more emails from {0}. Message to the user that they've unsubscribed and won't receive any more emails. {0} is replaced with the name of the site. - + {0} - registration opens {1} Page title prior to registration, {0} is replaced with the name of the site, {1} with the date registration opens - + Old Password Prompt a participant for their old password when they want to change their password - + Activity Title for the participant's activity - + Add an existing participant into your {0}, if that participant is the head of a {0} their {0} members will be moved into your {0} as well. Explanation of how adding an existing participant into the current participant's Group or Family works. {0} is replaced with either "Family" or "Group"as translated in this file. - + Add Existing Participant Title for area to add an existing program participant to the current participant's Family or Group - + Add Participant Button text to add a participant to a Group or Family - + Are you sure you want to delete this book from your book list: Prompt for the user when they request to delete a book from the list; the book name is specified directly after this message is printed. - + Book List Button to view the participant's book list. - + Bundle Items Title for a pop-up showing a collection of avatar items awarded as a bundle - + Cancel Button text to exit a dialog without saving changes. - + Change Password Button to change the user's password. - + Congratulations, you've earned a free book! Message to the participant that they've earned a free book. - + Date Heading or title to display a date - + Delete Button text to delete an item. - + Delete Book Title to delete a book from the participant's book list - + Details Button to view more details about the currently shown record. - + Donate your book Button text for the participant to donate their book to charity rather than redeem it for personal use. - + Edit Book Title to edit a book in the participant's book list - + Family Title shown when viewing a Family of participants. Will also be used in a sentence. - + Free book code Description of the code a customer will use for obtaining their free book that they've earned. - + Group Title shown when viewing a Group of participants. Will also be used in a sentence. - + Group name The name for a group of participants, for example a summer camp name. - + Group type The type for a group of participants, for example: summer camp or daycare - + History Button to view the participant's history. - + It appears that you have more than {0} members in your family. We'd like you to convert your family to a group in order to add more members. The participant is attempting to add an additional user to their family which pushes them over the family/group threshold to turn them into a group. - + No books logged. Message shown when the book list is viewed with no books in the log. - + No history to display. Message shown when the history is viewed with no entries in the log. - + Points Title for showing points earned by the participant - + Redeem your code Button text for the participant to obtain their code for a free book. - + Total Points Heading shown before the total number of participant's points - + Update Group details Title for updating group details - + Upgrade from Family to Group Title for interface to upgrade a Family to a Group - + Upgrade to Group Button text for upgrading a family to a group - - If you can't find something, please <a href=\"{0}\">send us a mail</a> and let us know what you were looking for, we'll do our best to help. + + If you can't find something, please <a href="{0}">send us a mail</a> and let us know what you were looking for, we'll do our best to help. Ask participant to use the in-software mail facility to contact site owners if they require assistance; {0} will be replaced automatically with the URL to the mail facility. - + Page not found Page title and header for 404 not found error. - + We couldn't find what you were looking for. Sorry about that! Explain to user a 404 not found error. - + Are you sure you wish to delete this mail: {0} Confirm message deletion, {0} is replaced with the mail subject. - + Back to Mailbox Button to return to the participant's mailbox - + Delete Mail Header for delete mail page/dialog - + Mail message Display prompt for mail content - + Mail sent: {0} Inform a participant that their mail was sent, {0} is replaced with the subject of the mail. - + Re: {0} The subject of a message is changed to this when it is replied to with {0} replaced with the original subject. - + Read Button to read a mail. - + Reply Button to reply to a mail - + Reply to: Inform a participant what they are replying to, the subject is output after this message. Should end with an indicator that text follows such as a colon (:) - + Send Mail Button to send a mail, also used as a page/dialog header - + Send Reply Button to send a reply to a mail - + Sent to you on {0} Inform a participant when a mail was sent to them. - + Subject Header/display prompt for a mail subject - + Subject: {0} Show the subject of a mail; {0} is replaced with the mail subject - + There was an issue deleting that mail item. Unable to delete a mail due to a software error. - + Unable to read mail: {0} Unable to display a mail due to a software error, {0} is replaced with the text of the error. - + Unable to reply to mail: {0} Unable to reply to a mail due to a software error, {0} is replaced with the text of the error. - + You currently have no mail. Inform a participant that their mailbox is empty. - + You must select a branch. Inform the user they must select a library branch. - + You must select a program. Inform the user they must select a program. - + You must select a system. Inform the user they must select a library system. - + Activity cannot be logged for this participant until they log in and answer a questionnaire. The designated participant must log in to complete a questionnaire before activity can be entered for them. - + Add username Add a username for a participant who doesn't have one so that they can log in on their own - + Apply Button text shown after a secret code entry field to apply the code - + Book Code Column heading for free book codes/vendor codes, a participant redeems this to obtain their free book - + Donate book Donate a free book for the currently-selected participant - + New Mail! Tool tip to show when a user has new mail - + Participant Column header to describe a person that is participating in the program - + Redeem code Redeem a free book/vendor code for the currently-selected participant - + Return to Top Link or button on the bottom of a page to return to the top of the page or list - + Switch To Switched the logged in user to another participant - + Your session has expired. Please sign in again. The participant's session has expired, they must sign in again to access the application. - + A {0} cannot be created at this time. Shown when an error occurs creating a family or group; {0} is replaced with the translation of Group or Family - + Add existing participant to your {0} Add an existing participant to a group/family, {0} is replaced with the translation of Group or Family - + Click below to create a {0} Instruction to click a link below in order to create a group or family, {0} is replaced with the translation of Group or Family - + Register new {0} Member Register a new member, {0} is replaced with the translation of Group or Family - + You are in the group: <strong>{0}</strong> Text indicating that the participant is a member of a group; {0} is replaced with the name of the group. - - You are leader of the group: <a href=\"{0}\"><strong>{1}</strong></a> + + You are leader of the group: <a href="{0}"><strong>{1}</strong></a> Text with a link indicating that the participant is the leader of a group; {0} is replaced with the URL to group management and {1} will be replaced with the name of the group. - + Back to {0} Return to the prior page; {0} will be replaced with the name of the page - + minutes Minutes, plural - + Activity applied! Resposne message after activity has been applied to a family or group. - + Added {0} to your {1}! Inform that a participant was added to a family or group; {0} is the participant's full name, {1} is the translation of Group or Family - + All selected participants already have that Secret Code. Participant tried to applly a secret code to a family/group but they've all already entered that secret code. - + Could not create {0}: {1} An item could not be created, {0} indicates what was attempted to be created at {1} indicates why it could not be. - + Could not remove {0}: {1} An item could not be removed, {0} indicates what was attempted to be removed and {1} indicates why it could not be. - + Could not update {0}: {1}. An item could not be updated, {0} indicates what was attempted to be updated and {1} inticates why it could not be. - + Group name is required. When promoting a family to a group it is necessary for the participant to supply a name for the group which they have neglected to do. - + Please select some participants first. A participant is trying to apply actions to their family/group but has not selected any family/group members. - + Removed: {0} An item was removed, {0} indicates what that item is (typically by name) - + Required fields are blank. Information was submitted but some required fields were not provided. - + Secret code applied! Response message after a secret code has been applied to a family or group. - + See the items you unlocked. Hyperlinked text to navigate a participant to avatar parts that were unlocked as part of a bundle. - + Something went wrong, please send us a mail with details of what you were attempting to do. An application error occurred; message suggests to the user that they should use the mail system in the application to let the administrators know what went wrong. - + Unable to add: {0} An attempt to add something failed, {0} describes what could not be added. - + Unable to change your password: {0} Changing passwords failed; {0} is replaced with why the process failed. - + Updated: {0} An item was updated, {0} indicated what that item was (typically by name) - + You are now signed in as {0}. Message displayed when someone in a group/family logs in as a member of their group/family. - + You must enter an amount. Inform a participant that they must enter an amount in order to apply an activity to multiple members of their family/group. - + Your password has been changed. Inform a participant that their password was successfully changed. - + ...and other activities. Displayed when there are more than a few notifications; links to the participant's profile so they can view their other accomplishments. - + You've successfully joined <strong>{0}</strong>! Message shown when a participant signs up, {0} is replaced with the name of the site. - + and their {0} When one family/group is absorbed into another, this is displayed; {0} is replaced with the translated term for Group or Family - + Profile updated. Message shown once a profile update is saved. - + Select a Bundle A bundle is a collection of avatar parts that are unlocked during participation. This text goes in a drop-down allowing the user to select a particular bundle to explore the parts it contains. diff --git a/src/GRA/Resources/Shared.es.resx b/src/GRA/Resources/Shared.es.resx index b541929b5..9bde98082 100644 --- a/src/GRA/Resources/Shared.es.resx +++ b/src/GRA/Resources/Shared.es.resx @@ -502,7 +502,7 @@ Page title/call to action for joining; {0} is the name of the program - {0} cada díay + {0} cada día Daily personal goal, completion of sentence, {0} is a plural activity description such as "minutes". See 'I will {0}' for the first half of this sentence - when combined they will say something similar to "I will read _ minutes a day" @@ -682,7 +682,7 @@ Column title showing events: where the event occurs - Credencial + Medalla Column heading showing which badge will be unlocked when a task is completed @@ -713,10 +713,6 @@ ¡Recuérdame! Submission button text for the participant's email address to be reminded prior to the program starting. - - ¡La lectura es fundamental para desarrollar las habilidades de alfabetización! - Landing page message informing that reading is fundamental for developing literacy skills. - Mientras este ahí, ¡vaya en un viaje de descubrimiento! ¡Visite a fabulosos destinos tal como Hogwarts, Narnia, Oz, y el centro de la tierra! @@ -862,12 +858,12 @@ Hogwarts, Narnia, Oz, y el centro de la tierra! Progreso Column heading showing far a participant is towards completing an item (i.e. their progress) - - Leer <strong><em><a href=\"{0}\" target=\"_blank\">{1}</a></em></strong> + + Leer <strong><em><a href="{0}" target=\"_blank\">{1}</a></em></strong> Challenge task of book with a link (replacing {0}) and a book title (replacing {1}) - - Leer <strong><em><a href=\"{0}\" target=\"_blank\">{1}</a></em></strong> por <strong>{2}</strong> + + Leer <strong><em><a href="{0}" target="_blank">{1}</a></em></strong> por <strong>{2}</strong> Challenge task of book with a link (replacing {0}), a book title (replacing {1}) and the author of the book (replacing {2}) @@ -898,12 +894,12 @@ Hogwarts, Narnia, Oz, y el centro de la tierra! Vea el archivo adjunto Button text to view an attached file to a challenge task - - Cuando completes <strong>{0}</strong>, ganarás <strong>{1}</strong> y credenciales. + + Al completar <strong>{0}</strong>, recibira <strong>{1}</strong> y una medalla. Describe what completing a challenge will achieve. {0} replaced with singular or plural task information (e.g. "1 task"or "2 tasks") and {1} is replaced with singular or plural point information (e.g. "1 point" or "2 points") - - Cuando completes <strong>{0}</strong>, ganarás <strong>{1}</strong>. + + Al completar <strong>{0}</strong>, recibira <strong>{1}</strong> y una medalla. Describe what completing a challenge will achieve. {0} replaced with singular or plural task information (e.g. "1 task"or "2 tasks") and {1} is replaced with singular or plural point information (e.g. "1 point" or "2 points") @@ -1082,8 +1078,8 @@ Hogwarts, Narnia, Oz, y el centro de la tierra! Actualizar a Grupo Button text for upgrading a family to a group - - Si no puede encontrar algo, por favor <a href=\"{0}\">envíenos un correo</a> y háganos saber lo que estaba buscando, haremos todo lo posible para ayudarlo. + + Si no puede encontrar algo, por favor <a href="{0}">envíenos un correo</a> y háganos saber lo que estaba buscando, haremos todo lo posible para ayudarlo. Ask participant to use the in-software mail facility to contact site owners if they require assistance; {0} will be replaced automatically with the URL to the mail facility. @@ -1242,8 +1238,8 @@ Hogwarts, Narnia, Oz, y el centro de la tierra! Estas en el grupo: <strong>{0}</strong> Text indicating that the participant is a member of a group; {0} is replaced with the name of the group. - - Eres el líder del grupo: <a href=\"{0}\"><strong>{1}</strong></a> + + Eres el líder del grupo: <a href="{0}"><strong>{1}</strong></a> Text with a link indicating that the participant is the leader of a group; {0} is replaced with the URL to group management and {1} will be replaced with the name of the group. @@ -1350,4 +1346,19 @@ Hogwarts, Narnia, Oz, y el centro de la tierra! Familia Title shown when viewing a Family of participants. Will also be used in a sentence. - \ No newline at end of file + + ¡Participacion Confirmada {0}! + Confirmation to the participant that they have joined the program. {0} is replaced with the name of the program. + + + ¡Gracias por participar {0}! + Thank visitors for participating in the program. {0} is replaced with the name of the program. + + + Ingrese a su sesión para revisar su historial y logros + + + Seleccione Su Paquete + A bundle is a collection of avatar parts that are unlocked during participation. This text goes in a drop-down allowing the user to select a particular bundle to explore the parts it contains. + + diff --git a/src/GRA/Utility/XmlParser.cs b/src/GRA/Utility/XmlParser.cs new file mode 100644 index 000000000..fc733c615 --- /dev/null +++ b/src/GRA/Utility/XmlParser.cs @@ -0,0 +1,24 @@ +using System.Collections.Generic; +using System.IO; +using System.Linq; +using System.Xml.Linq; + +namespace GRA.Utility +{ + public static class XmlParser + { + public static Dictionary ExtractDataNames(string filename, string path) + { + var finalDictionary = new Dictionary(); + var xmlFilepath = Path.Combine(path, filename); + foreach (var element in XElement.Load(xmlFilepath).Descendants("data")) + { + finalDictionary[element.Attribute("name").Value] = element + .Descendants("value") + .FirstOrDefault()? + .Value; + } + return finalDictionary; + } + } +} diff --git a/test/GRA.Test/GRA.Test.csproj b/test/GRA.Test/GRA.Test.csproj new file mode 100644 index 000000000..8969f7676 --- /dev/null +++ b/test/GRA.Test/GRA.Test.csproj @@ -0,0 +1,28 @@ + + + + netcoreapp2.2 + + false + + + + + + + + + + + + + + + + + + + + + + diff --git a/test/GRA.Test/VerifyResourcesTest.cs b/test/GRA.Test/VerifyResourcesTest.cs new file mode 100644 index 000000000..48a97b4c3 --- /dev/null +++ b/test/GRA.Test/VerifyResourcesTest.cs @@ -0,0 +1,80 @@ +using System; +using System.Collections.Generic; +using System.IO; +using System.Linq; +using System.Reflection; +using GRA.Domain.Model; +using GRA.Utility; +using Xunit; + +namespace GRA.Test +{ + public class VerifyResourcesTest + { + private const string BasePathToResx = "..{0}..{0}..{0}..{0}..{0}src{0}GRA{0}Resources"; + + private readonly string PathToResx; + + public VerifyResourcesTest() + { + PathToResx = Path.GetFullPath( + Path.Combine(AppContext.BaseDirectory, + string.Format(BasePathToResx, Path.DirectorySeparatorChar))); + } + + [Fact] + public void TestEnglishResxHasAllAnnotations() => TestResxHasAnnotations("Shared.en.resx"); + + [Fact] + public void TestSpanishResxHasAllAnnotations() => TestResxHasAnnotations("Shared.es.resx"); + + private void TestResxHasAnnotations(string filename) + { + var resourceFileKeys = XmlParser.ExtractDataNames(filename, PathToResx).Keys; + var annotationValues = new List(); + foreach (var classType in typeof(Annotations).GetNestedTypes(BindingFlags.Public)) + { + var constStrings = classType.GetFields(BindingFlags.Public + | BindingFlags.Static + | BindingFlags.FlattenHierarchy) + .Where(fi => fi.IsLiteral && !fi.IsInitOnly) + .ToList(); + + foreach (var constval in constStrings) + { + annotationValues.Add((string)constval.GetValue(null)); + } + } + + var displayNameValues = new List(); + var displayNameConstStrings = typeof(DisplayNames).GetFields(BindingFlags.Public + | BindingFlags.Static + | BindingFlags.FlattenHierarchy) + .Where(fi => fi.IsLiteral && !fi.IsInitOnly) + .ToList(); + foreach (var constval in displayNameConstStrings) + { + displayNameValues.Add((string)constval.GetValue(null)); + } + + var errorMessageValues = new List(); + var errorMessageConstStrings = typeof(ErrorMessages).GetFields(BindingFlags.Public + | BindingFlags.Static + | BindingFlags.FlattenHierarchy) + .Where(fi => fi.IsLiteral && !fi.IsInitOnly) + .ToList(); + foreach (var constval in errorMessageConstStrings) + { + errorMessageValues.Add((string)constval.GetValue(null)); + } + + var localizationValues = annotationValues + .Concat(displayNameValues) + .Concat(errorMessageValues); + + var missingItems = localizationValues.Except(resourceFileKeys); + + Assert.Empty(missingItems); + } + } +}